зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to tracemonkey.
This commit is contained in:
Коммит
67efa6c0c3
|
@ -54,9 +54,9 @@
|
|||
#include "nsIServiceManager.h"
|
||||
#include "nsIURI.h"
|
||||
|
||||
//-------------
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsLeafAccessible
|
||||
//-------------
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsLeafAccessible::nsLeafAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell):
|
||||
nsAccessibleWrap(aNode, aShell)
|
||||
|
@ -65,34 +65,6 @@ nsAccessibleWrap(aNode, aShell)
|
|||
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(nsLeafAccessible, nsAccessible)
|
||||
|
||||
/* nsIAccessible getFirstChild (); */
|
||||
NS_IMETHODIMP nsLeafAccessible::GetFirstChild(nsIAccessible **_retval)
|
||||
{
|
||||
*_retval = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* nsIAccessible getLastChild (); */
|
||||
NS_IMETHODIMP nsLeafAccessible::GetLastChild(nsIAccessible **_retval)
|
||||
{
|
||||
*_retval = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* long getAccChildCount (); */
|
||||
NS_IMETHODIMP nsLeafAccessible::GetChildCount(PRInt32 *_retval)
|
||||
{
|
||||
*_retval = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsAccessible::GetAllowsAnonChildAccessibles()
|
||||
PRBool
|
||||
nsLeafAccessible::GetAllowsAnonChildAccessibles()
|
||||
{
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// nsAccessible::GetChildAtPoint()
|
||||
nsresult
|
||||
nsLeafAccessible::GetChildAtPoint(PRInt32 aX, PRInt32 aY,
|
||||
|
@ -104,19 +76,29 @@ nsLeafAccessible::GetChildAtPoint(PRInt32 aX, PRInt32 aY,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsAccessible::CacheChildren()
|
||||
void
|
||||
nsLeafAccessible::CacheChildren()
|
||||
{
|
||||
// No children for leaf accessible.
|
||||
mAccChildCount = IsDefunct() ? eChildCountUninitialized : 0;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsLinkableAccessible
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsLinkableAccessible::
|
||||
nsLinkableAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell) :
|
||||
nsHyperTextAccessibleWrap(aNode, aShell),
|
||||
nsAccessibleWrap(aNode, aShell),
|
||||
mActionContent(nsnull),
|
||||
mIsLink(PR_FALSE),
|
||||
mIsOnclick(PR_FALSE)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(nsLinkableAccessible, nsHyperTextAccessibleWrap)
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(nsLinkableAccessible, nsAccessibleWrap)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsLinkableAccessible. nsIAccessible
|
||||
|
@ -128,14 +110,13 @@ nsLinkableAccessible::TakeFocus()
|
|||
if (actionAcc)
|
||||
return actionAcc->TakeFocus();
|
||||
|
||||
return nsHyperTextAccessibleWrap::TakeFocus();
|
||||
return nsAccessibleWrap::TakeFocus();
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsLinkableAccessible::GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState)
|
||||
{
|
||||
nsresult rv = nsHyperTextAccessibleWrap::GetStateInternal(aState,
|
||||
aExtraState);
|
||||
nsresult rv = nsAccessibleWrap::GetStateInternal(aState, aExtraState);
|
||||
NS_ENSURE_A11Y_SUCCESS(rv, rv);
|
||||
|
||||
if (mIsLink) {
|
||||
|
@ -153,7 +134,7 @@ nsLinkableAccessible::GetValue(nsAString& aValue)
|
|||
{
|
||||
aValue.Truncate();
|
||||
|
||||
nsHyperTextAccessible::GetValue(aValue);
|
||||
nsAccessible::GetValue(aValue);
|
||||
if (!aValue.IsEmpty())
|
||||
return NS_OK;
|
||||
|
||||
|
@ -206,7 +187,7 @@ nsLinkableAccessible::DoAction(PRUint8 aIndex)
|
|||
if (actionAcc)
|
||||
return actionAcc->DoAction(aIndex);
|
||||
|
||||
return nsHyperTextAccessibleWrap::DoAction(aIndex);
|
||||
return nsAccessibleWrap::DoAction(aIndex);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -250,14 +231,14 @@ nsresult
|
|||
nsLinkableAccessible::Init()
|
||||
{
|
||||
CacheActionContent();
|
||||
return nsHyperTextAccessibleWrap::Init();
|
||||
return nsAccessibleWrap::Init();
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsLinkableAccessible::Shutdown()
|
||||
{
|
||||
mActionContent = nsnull;
|
||||
return nsHyperTextAccessibleWrap::Shutdown();
|
||||
return nsAccessibleWrap::Shutdown();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -62,24 +62,24 @@ public:
|
|||
// nsISupports
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
// nsIAccessible
|
||||
NS_IMETHOD GetFirstChild(nsIAccessible **_retval);
|
||||
NS_IMETHOD GetLastChild(nsIAccessible **_retval);
|
||||
NS_IMETHOD GetChildCount(PRInt32 *_retval);
|
||||
|
||||
// nsAccessible
|
||||
virtual nsresult GetChildAtPoint(PRInt32 aX, PRInt32 aY,
|
||||
PRBool aDeepestChild,
|
||||
nsIAccessible **aChild);
|
||||
virtual PRBool GetAllowsAnonChildAccessibles();
|
||||
|
||||
protected:
|
||||
|
||||
// nsAccessible
|
||||
virtual void CacheChildren();
|
||||
};
|
||||
|
||||
/**
|
||||
* A type of accessible for DOM nodes containing an href="" attribute.
|
||||
* It knows how to report the state of the link ( traveled or not )
|
||||
* and can activate ( click ) the link programmatically.
|
||||
*/
|
||||
class nsLinkableAccessible : public nsHyperTextAccessibleWrap
|
||||
* Used for text or image accessible nodes contained by link accessibles or
|
||||
* accessibles for nodes with registered click event handler. It knows how to
|
||||
* report the state of the host link (traveled or not) and can activate (click)
|
||||
* the host accessible programmatically.
|
||||
*/
|
||||
class nsLinkableAccessible : public nsAccessibleWrap
|
||||
{
|
||||
public:
|
||||
enum { eAction_Jump = 0 };
|
||||
|
@ -96,7 +96,7 @@ public:
|
|||
NS_IMETHOD TakeFocus();
|
||||
NS_IMETHOD GetKeyboardShortcut(nsAString& _retval);
|
||||
|
||||
// nsIHyperLinkAccessible
|
||||
// nsIAccessibleHyperLink
|
||||
NS_IMETHOD GetURI(PRInt32 i, nsIURI **aURI);
|
||||
|
||||
// nsAccessNode
|
||||
|
|
|
@ -38,27 +38,18 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
// NOTE: alphabetically ordered
|
||||
#include "nsTextAccessible.h"
|
||||
|
||||
// ------------
|
||||
// Text Accessibles
|
||||
// ------------
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsTextAccessible
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsTextAccessible::nsTextAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell):
|
||||
nsLinkableAccessible(aDOMNode, aShell)
|
||||
{
|
||||
nsTextAccessible::
|
||||
nsTextAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell) :
|
||||
nsLinkableAccessible(aDOMNode, aShell)
|
||||
{
|
||||
}
|
||||
|
||||
// Make sure we don't support text or other irrelevant interfaces.
|
||||
// We have nsLinkableAccessible in our inheritance chain as a convenience in order to
|
||||
// get link actions and states on the text accessibles. Windows screen readers expect that.
|
||||
NS_IMPL_ISUPPORTS_INHERITED2(nsTextAccessible, nsAccessNode,
|
||||
nsAccessible, nsIAccessible)
|
||||
|
||||
/**
|
||||
* We are text
|
||||
*/
|
||||
nsresult
|
||||
nsTextAccessible::GetRoleInternal(PRUint32 *aRole)
|
||||
{
|
||||
|
@ -66,33 +57,6 @@ nsTextAccessible::GetRoleInternal(PRUint32 *aRole)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* No Children
|
||||
*/
|
||||
NS_IMETHODIMP nsTextAccessible::GetFirstChild(nsIAccessible **_retval)
|
||||
{
|
||||
*_retval = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* No Children
|
||||
*/
|
||||
NS_IMETHODIMP nsTextAccessible::GetLastChild(nsIAccessible **_retval)
|
||||
{
|
||||
*_retval = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* No Children
|
||||
*/
|
||||
NS_IMETHODIMP nsTextAccessible::GetChildCount(PRInt32 *_retval)
|
||||
{
|
||||
*_retval = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsTextAccessible::AppendTextTo(nsAString& aText, PRUint32 aStartOffset, PRUint32 aLength)
|
||||
{
|
||||
|
@ -102,3 +66,9 @@ nsTextAccessible::AppendTextTo(nsAString& aText, PRUint32 aStartOffset, PRUint32
|
|||
return frame->GetRenderedText(&aText, nsnull, nsnull, aStartOffset, aLength);
|
||||
}
|
||||
|
||||
void
|
||||
nsTextAccessible::CacheChildren()
|
||||
{
|
||||
// No children for text accessible.
|
||||
mAccChildCount = IsDefunct() ? eChildCountUninitialized : 0;
|
||||
}
|
||||
|
|
|
@ -41,27 +41,23 @@
|
|||
|
||||
#include "nsBaseWidgetAccessible.h"
|
||||
|
||||
/**
|
||||
* Text nodes have no children, but since double inheritance
|
||||
* no-worky we have to re-impl the LeafAccessiblity blocks
|
||||
* this way.
|
||||
*/
|
||||
/**
|
||||
* Generic class used for text nodes.
|
||||
*/
|
||||
class nsTextAccessible : public nsLinkableAccessible
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
nsTextAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell);
|
||||
|
||||
// nsIAccessible
|
||||
NS_IMETHOD GetFirstChild(nsIAccessible **_retval);
|
||||
NS_IMETHOD GetLastChild(nsIAccessible **_retval);
|
||||
NS_IMETHOD GetChildCount(PRInt32 *_retval);
|
||||
|
||||
// nsAccessible
|
||||
virtual nsresult GetRoleInternal(PRUint32 *aRole);
|
||||
virtual nsresult AppendTextTo(nsAString& aText, PRUint32 aStartOffset,
|
||||
PRUint32 aLength);
|
||||
|
||||
protected:
|
||||
|
||||
// nsAccessible
|
||||
virtual void CacheChildren();
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -47,12 +47,13 @@
|
|||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsHTMLAreaAccessible
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsHTMLAreaAccessible::
|
||||
nsHTMLAreaAccessible(nsIDOMNode *aDomNode, nsIAccessible *aParent,
|
||||
nsIWeakReference* aShell):
|
||||
nsHTMLLinkAccessible(aDomNode, aShell)
|
||||
{
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -89,33 +90,6 @@ nsHTMLAreaAccessible::GetDescription(nsAString& aDescription)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLAreaAccessible::GetFirstChild(nsIAccessible **aChild)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aChild);
|
||||
|
||||
*aChild = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLAreaAccessible::GetLastChild(nsIAccessible **aChild)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aChild);
|
||||
|
||||
*aChild = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLAreaAccessible::GetChildCount(PRInt32 *aCount)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aCount);
|
||||
|
||||
*aCount = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLAreaAccessible::GetBounds(PRInt32 *x, PRInt32 *y,
|
||||
PRInt32 *width, PRInt32 *height)
|
||||
|
@ -161,7 +135,9 @@ nsHTMLAreaAccessible::GetBounds(PRInt32 *x, PRInt32 *y,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsAccessible::GetChildAtPoint()
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsAccessible public implementation
|
||||
|
||||
nsresult
|
||||
nsHTMLAreaAccessible::GetChildAtPoint(PRInt32 aX, PRInt32 aY,
|
||||
PRBool aDeepestChild,
|
||||
|
@ -171,3 +147,13 @@ nsHTMLAreaAccessible::GetChildAtPoint(PRInt32 aX, PRInt32 aY,
|
|||
NS_ADDREF(*aChild = this);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsAccessible protected implementation
|
||||
|
||||
void
|
||||
nsHTMLAreaAccessible::CacheChildren()
|
||||
{
|
||||
// No children for aria accessible.
|
||||
mAccChildCount = IsDefunct() ? eChildCountUninitialized : 0;
|
||||
}
|
||||
|
|
|
@ -41,9 +41,9 @@
|
|||
|
||||
#include "nsHTMLLinkAccessible.h"
|
||||
|
||||
/* Accessible for image map areas - must be child of image
|
||||
/**
|
||||
* Accessible for image map areas - must be child of image.
|
||||
*/
|
||||
|
||||
class nsHTMLAreaAccessible : public nsHTMLLinkAccessible
|
||||
{
|
||||
|
||||
|
@ -54,10 +54,6 @@ public:
|
|||
// nsIAccessible
|
||||
NS_IMETHOD GetDescription(nsAString& aDescription);
|
||||
|
||||
NS_IMETHOD GetFirstChild(nsIAccessible **_retval);
|
||||
NS_IMETHOD GetLastChild(nsIAccessible **_retval);
|
||||
NS_IMETHOD GetChildCount(PRInt32 *_retval);
|
||||
|
||||
NS_IMETHOD GetBounds(PRInt32 *x, PRInt32 *y, PRInt32 *width, PRInt32 *height);
|
||||
|
||||
// nsAccessible
|
||||
|
@ -65,6 +61,11 @@ public:
|
|||
virtual nsresult GetChildAtPoint(PRInt32 aX, PRInt32 aY,
|
||||
PRBool aDeepestChild,
|
||||
nsIAccessible **aChild);
|
||||
|
||||
protected:
|
||||
|
||||
// nsAccessible
|
||||
virtual void CacheChildren();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -57,6 +57,8 @@ nsTextAccessibleWrap(aDomNode, aShell)
|
|||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(nsHTMLTextAccessible, nsTextAccessible)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLTextAccessible::GetName(nsAString& aName)
|
||||
{
|
||||
|
|
|
@ -50,7 +50,10 @@ class nsHTMLTextAccessible : public nsTextAccessibleWrap
|
|||
{
|
||||
public:
|
||||
nsHTMLTextAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell);
|
||||
|
||||
|
||||
// nsISupports
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
// nsIAccessible
|
||||
NS_IMETHOD GetName(nsAString& aName);
|
||||
|
||||
|
|
|
@ -44,6 +44,6 @@ NS_IMPL_ISUPPORTS_INHERITED0(nsHTMLImageAccessibleWrap,
|
|||
nsHTMLImageAccessible)
|
||||
|
||||
IMPL_IUNKNOWN_INHERITED1(nsHTMLImageAccessibleWrap,
|
||||
nsHyperTextAccessibleWrap,
|
||||
nsAccessibleWrap,
|
||||
CAccessibleImage);
|
||||
|
||||
|
|
|
@ -41,11 +41,8 @@
|
|||
#define _nsXULTextAccessible_H_
|
||||
|
||||
#include "nsBaseWidgetAccessible.h"
|
||||
#include "nsTextAccessibleWrap.h"
|
||||
#include "nsHyperTextAccessibleWrap.h"
|
||||
|
||||
class nsIWeakReference;
|
||||
|
||||
class nsXULTextAccessible : public nsHyperTextAccessibleWrap
|
||||
{
|
||||
|
||||
|
|
|
@ -311,7 +311,6 @@ pref("browser.microsummary.updateGenerators", true);
|
|||
// enable search suggestions by default
|
||||
pref("browser.search.suggest.enabled", true);
|
||||
|
||||
pref("browser.history.showSessions", false);
|
||||
pref("browser.sessionhistory.max_entries", 50);
|
||||
pref("browser.history_expire_days", 180);
|
||||
pref("browser.history_expire_days_min", 90);
|
||||
|
@ -363,10 +362,6 @@ pref("browser.allTabs.previews", false);
|
|||
pref("browser.ctrlTab.previews", false);
|
||||
pref("browser.ctrlTab.recentlyUsedLimit", 7);
|
||||
|
||||
// Default bookmark sorting
|
||||
pref("browser.bookmarks.sort.direction", "descending");
|
||||
pref("browser.bookmarks.sort.resource", "rdf:http://home.netscape.com/NC-rdf#Name");
|
||||
|
||||
// By default, do not export HTML at shutdown.
|
||||
// If true, at shutdown the bookmarks in your menu and toolbar will
|
||||
// be exported as HTML to the bookmarks.html file.
|
||||
|
@ -376,7 +371,7 @@ pref("browser.bookmarks.autoExportHTML", false);
|
|||
// keep in {PROFILEDIR}/bookmarkbackups. Special values:
|
||||
// -1: unlimited
|
||||
// 0: no backups created (and deletes all existing backups)
|
||||
pref("browser.bookmarks.max_backups", 5);
|
||||
pref("browser.bookmarks.max_backups", 10);
|
||||
|
||||
// Scripts & Windows prefs
|
||||
pref("dom.disable_open_during_load", true);
|
||||
|
|
|
@ -265,7 +265,7 @@ function getModifiedPrefs() {
|
|||
function getWhitelistedPrefNames() {
|
||||
let results = [];
|
||||
PREFS_WHITELIST.forEach(function (prefStem) {
|
||||
let prefNames = gPrefService.getChildList(prefStem, {});
|
||||
let prefNames = gPrefService.getChildList(prefStem);
|
||||
results = results.concat(prefNames);
|
||||
});
|
||||
return results;
|
||||
|
|
|
@ -682,8 +682,8 @@ let gGestureSupport = {
|
|||
let addRemove = aAddListener ? window.addEventListener :
|
||||
window.removeEventListener;
|
||||
|
||||
for each (let event in gestureEvents)
|
||||
addRemove("Moz" + event, this, true);
|
||||
gestureEvents.forEach(function (event) addRemove("Moz" + event, this, true),
|
||||
this);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -871,9 +871,10 @@ let gGestureSupport = {
|
|||
*/
|
||||
onSwipe: function GS_onSwipe(aEvent) {
|
||||
// Figure out which one (and only one) direction was triggered
|
||||
for each (let dir in ["UP", "RIGHT", "DOWN", "LEFT"])
|
||||
["UP", "RIGHT", "DOWN", "LEFT"].forEach(function (dir) {
|
||||
if (aEvent.direction == aEvent["DIRECTION_" + dir])
|
||||
return this._doAction(aEvent, ["swipe", dir.toLowerCase()]);
|
||||
}, this);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1540,8 +1541,7 @@ function initializeSanitizer()
|
|||
*/
|
||||
if (!gPrefService.getBoolPref("privacy.sanitize.migrateFx3Prefs")) {
|
||||
let itemBranch = gPrefService.getBranch("privacy.item.");
|
||||
let itemCount = { value: 0 };
|
||||
let itemArray = itemBranch.getChildList("", itemCount);
|
||||
let itemArray = itemBranch.getChildList("");
|
||||
|
||||
// See if any privacy.item prefs are set
|
||||
let doMigrate = itemArray.some(function (name) itemBranch.prefHasUserValue(name));
|
||||
|
@ -2085,10 +2085,9 @@ function BrowserViewSourceOfDocument(aDocument)
|
|||
|
||||
// doc - document to use for source, or null for this window's document
|
||||
// initialTab - name of the initial tab to display, or null for the first tab
|
||||
// imageUrl - url of an image to load in the Media Tab of the Page Info window; can be null/omitted
|
||||
function BrowserPageInfo(doc, initialTab, imageUrl)
|
||||
{
|
||||
var args = {doc: doc, initialTab: initialTab, imageUrl: imageUrl};
|
||||
// imageElement - image to load in the Media Tab of the Page Info window; can be null/omitted
|
||||
function BrowserPageInfo(doc, initialTab, imageElement) {
|
||||
var args = {doc: doc, initialTab: initialTab, imageElement: imageElement};
|
||||
return toOpenDialogByTypeAndUrl("Browser:page-info",
|
||||
doc ? doc.location : window.content.document.location,
|
||||
"chrome://browser/content/pageinfo/pageInfo.xul",
|
||||
|
@ -2631,7 +2630,7 @@ function FillInHTMLTooltip(tipElement)
|
|||
var tipNode = document.getElementById("aHTMLTooltip");
|
||||
tipNode.style.direction = direction;
|
||||
|
||||
for each (var t in [titleText, XLinkTitleText]) {
|
||||
[titleText, XLinkTitleText].forEach(function (t) {
|
||||
if (t && /\S/.test(t)) {
|
||||
|
||||
// Per HTML 4.01 6.2 (CDATA section), literal CRs and tabs should be
|
||||
|
@ -2645,7 +2644,7 @@ function FillInHTMLTooltip(tipElement)
|
|||
tipNode.setAttribute("label", t);
|
||||
retVal = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
|
|
@ -258,7 +258,7 @@ nsContextMenu.prototype = {
|
|||
document.getElementById("context-viewbgimage")
|
||||
.disabled = !this.hasBGImage;
|
||||
|
||||
this.showItem("context-viewimageinfo", (this.onImage));
|
||||
this.showItem("context-viewimageinfo", this.onImage);
|
||||
},
|
||||
|
||||
initMiscItems: function CM_initMiscItems() {
|
||||
|
@ -779,7 +779,8 @@ nsContextMenu.prototype = {
|
|||
},
|
||||
|
||||
viewImageInfo: function() {
|
||||
BrowserPageInfo(this.target.ownerDocument.defaultView.top.document,"mediaTab",this.mediaURL);
|
||||
BrowserPageInfo(this.target.ownerDocument.defaultView.top.document,
|
||||
"mediaTab", this.target);
|
||||
},
|
||||
|
||||
viewFrameInfo: function() {
|
||||
|
|
|
@ -88,7 +88,8 @@ let gOpenLocationLastURL = {
|
|||
}
|
||||
},
|
||||
reset: function() {
|
||||
prefSvc.clearUserPref(LAST_URL_PREF);
|
||||
if (prefSvc.prefHasUserValue(LAST_URL_PREF))
|
||||
prefSvc.clearUserPref(LAST_URL_PREF);
|
||||
gOpenLocationLastURLData = "";
|
||||
}
|
||||
};
|
||||
|
|
|
@ -148,7 +148,7 @@ pageInfoTreeView.prototype = {
|
|||
// mmm, yummy. global variables.
|
||||
var gWindow = null;
|
||||
var gDocument = null;
|
||||
var gImageUrl = null;
|
||||
var gImageElement = null;
|
||||
|
||||
// column number to help using the data array
|
||||
const COL_IMAGE_ADDRESS = 0;
|
||||
|
@ -296,10 +296,10 @@ function onLoadPageInfo()
|
|||
var imageTree = document.getElementById("imagetree");
|
||||
imageTree.view = gImageView;
|
||||
|
||||
// set gImageUrl if present
|
||||
// set gImageElement if present
|
||||
if ("arguments" in window && window.arguments.length >= 1 &&
|
||||
window.arguments[0] && window.arguments[0].imageUrl)
|
||||
gImageUrl = window.arguments[0].imageUrl;
|
||||
window.arguments[0].imageElement)
|
||||
gImageElement = window.arguments[0].imageElement;
|
||||
|
||||
// build the content
|
||||
loadPageInfo();
|
||||
|
@ -531,7 +531,7 @@ function processFrames()
|
|||
var iterator = doc.createTreeWalker(doc, NodeFilter.SHOW_ELEMENT, grabAll, true);
|
||||
gFrameList.shift();
|
||||
setTimeout(doGrab, 16, iterator);
|
||||
onFinished.push(selectImgUrl);
|
||||
onFinished.push(selectImage);
|
||||
}
|
||||
else
|
||||
onFinished.forEach(function(func) { func(); });
|
||||
|
@ -1171,16 +1171,15 @@ function doSelectAll()
|
|||
elem.view.selection.selectAll();
|
||||
}
|
||||
|
||||
function selectImgUrl ()
|
||||
{
|
||||
if (gImageUrl) {
|
||||
var tree = document.getElementById("imagetree");
|
||||
for (var c = 0; c < tree.view.rowCount; c++)
|
||||
{
|
||||
if (gImageUrl == gImageView.data[c][COL_IMAGE_ADDRESS]) {
|
||||
tree.view.selection.select(c);
|
||||
return;
|
||||
}
|
||||
function selectImage() {
|
||||
if (!gImageElement)
|
||||
return;
|
||||
|
||||
var tree = document.getElementById("imagetree");
|
||||
for (var i = 0; i < tree.view.rowCount; i++) {
|
||||
if (gImageElement == gImageView.data[i][COL_IMAGE_NODE]) {
|
||||
tree.view.selection.select(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -90,7 +90,8 @@ function disableAddons() {
|
|||
// Select the default theme
|
||||
var prefB = Components.classes["@mozilla.org/preferences-service;1"]
|
||||
.getService(Components.interfaces.nsIPrefBranch);
|
||||
prefB.clearUserPref("general.skins.selectedSkin");
|
||||
if (prefB.prefHasUserValue("general.skins.selectedSkin"))
|
||||
prefB.clearUserPref("general.skins.selectedSkin");
|
||||
|
||||
// Disable plugins
|
||||
var phs = Components.classes["@mozilla.org/plugin/host;1"]
|
||||
|
|
|
@ -38,13 +38,10 @@
|
|||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
if (Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager).activeWindow !=
|
||||
window) {
|
||||
setTimeout(test, 0);
|
||||
window.focus();
|
||||
return;
|
||||
}
|
||||
waitForFocus(continue_test);
|
||||
}
|
||||
|
||||
function continue_test() {
|
||||
let charsToDelete, deletedURLTab, fullURLTab, partialURLTab, testPartialURL, testURL;
|
||||
|
||||
charsToDelete = 5;
|
||||
|
@ -108,7 +105,8 @@ function test() {
|
|||
|
||||
urlbarBackspace(function () {
|
||||
is(gURLBar.value, "", 'gURLBar.value should be "" (just set)');
|
||||
gPrefService.clearUserPref("browser.urlbar.clickSelectsAll");
|
||||
if (gPrefService.prefHasUserValue("browser.urlbar.clickSelectsAll"))
|
||||
gPrefService.clearUserPref("browser.urlbar.clickSelectsAll");
|
||||
cb();
|
||||
});
|
||||
}
|
||||
|
@ -133,7 +131,8 @@ function test() {
|
|||
urlbarBackspace(arguments.callee);
|
||||
} else {
|
||||
is(gURLBar.value, testPartialURL, "gURLBar.value should be testPartialURL (just set)");
|
||||
gPrefService.clearUserPref("browser.urlbar.clickSelectsAll");
|
||||
if (gPrefService.prefHasUserValue("browser.urlbar.clickSelectsAll"))
|
||||
gPrefService.clearUserPref("browser.urlbar.clickSelectsAll");
|
||||
cb();
|
||||
}
|
||||
});
|
||||
|
|
|
@ -85,7 +85,8 @@ function runPrintPreviewTests() {
|
|||
testPrintPreview(gTab1, function() {
|
||||
// test print preview of HTML document with siteSpecific set to false
|
||||
testPrintPreview(gTab2, function() {
|
||||
gPrefService.clearUserPref("browser.zoom.siteSpecific");
|
||||
if (gPrefService.prefHasUserValue("browser.zoom.siteSpecific"))
|
||||
gPrefService.clearUserPref("browser.zoom.siteSpecific");
|
||||
finishTest();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -23,7 +23,8 @@ function test() {
|
|||
tab2Zoom = ZoomManager.getZoomForBrowser(tab2.linkedBrowser);
|
||||
isnot(tab1Zoom, tab2Zoom, "Zoom should not affect background tabs");
|
||||
|
||||
gPrefService.clearUserPref("browser.zoom.updateBackgroundTabs");
|
||||
if (gPrefService.prefHasUserValue("browser.zoom.updateBackgroundTabs"))
|
||||
gPrefService.clearUserPref("browser.zoom.updateBackgroundTabs");
|
||||
gBrowser.removeTab(tab1);
|
||||
gBrowser.removeTab(tab2);
|
||||
finish();
|
||||
|
|
|
@ -11,5 +11,6 @@ function test() {
|
|||
is(gBrowser.mTabs.length, 1, "a new tab has been opened");
|
||||
is(document.activeElement, gURLBar.inputField, "location bar is focused for the new tab");
|
||||
|
||||
gPrefService.clearUserPref("browser.tabs.closeWindowWithLastTab");
|
||||
if (gPrefService.prefHasUserValue("browser.tabs.closeWindowWithLastTab"))
|
||||
gPrefService.clearUserPref("browser.tabs.closeWindowWithLastTab");
|
||||
}
|
||||
|
|
|
@ -84,7 +84,8 @@ function test() {
|
|||
}
|
||||
|
||||
// cleanup
|
||||
gPrefService.clearUserPref("browser.ctrlTab.previews");
|
||||
if (gPrefService.prefHasUserValue("browser.ctrlTab.previews"))
|
||||
gPrefService.clearUserPref("browser.ctrlTab.previews");
|
||||
|
||||
finish();
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ function testExpertPref() {
|
|||
|
||||
// Clean up
|
||||
gBrowser.removeCurrentTab();
|
||||
gPrefService.clearUserPref("browser.xul.error_pages.expert_bad_cert");
|
||||
if (gPrefService.prefHasUserValue("browser.xul.error_pages.expert_bad_cert"))
|
||||
gPrefService.clearUserPref("browser.xul.error_pages.expert_bad_cert");
|
||||
finish();
|
||||
}
|
||||
|
|
|
@ -806,7 +806,7 @@ WebContentConverterRegistrar.prototype = {
|
|||
* branch and stop cycling once that's true. This doesn't fix the case
|
||||
* where a user manually removes a reader, but that's not supported yet!
|
||||
*/
|
||||
var vals = branch.getChildList("", {});
|
||||
var vals = branch.getChildList("");
|
||||
if (vals.length == 0)
|
||||
return;
|
||||
|
||||
|
@ -832,7 +832,7 @@ WebContentConverterRegistrar.prototype = {
|
|||
getService(Ci.nsIPrefService);
|
||||
|
||||
var kids = ps.getBranch(PREF_CONTENTHANDLERS_BRANCH)
|
||||
.getChildList("", {});
|
||||
.getChildList("");
|
||||
|
||||
// first get the numbers of the providers by getting all ###.uri prefs
|
||||
var nums = [];
|
||||
|
@ -857,7 +857,7 @@ WebContentConverterRegistrar.prototype = {
|
|||
// so that getWebContentHandlerByURI can return successfully.
|
||||
try {
|
||||
var autoBranch = ps.getBranch(PREF_CONTENTHANDLERS_AUTO);
|
||||
var childPrefs = autoBranch.getChildList("", { });
|
||||
var childPrefs = autoBranch.getChildList("");
|
||||
for (var i = 0; i < childPrefs.length; ++i) {
|
||||
var type = childPrefs[i];
|
||||
var uri = autoBranch.getCharPref(type);
|
||||
|
|
|
@ -453,7 +453,10 @@ var MigrationWizard = {
|
|||
var prefBranch = prefSvc.getBranch(null);
|
||||
|
||||
if (this._newHomePage == "DEFAULT") {
|
||||
prefBranch.clearUserPref("browser.startup.homepage");
|
||||
try {
|
||||
prefBranch.clearUserPref("browser.startup.homepage");
|
||||
}
|
||||
catch (e) { }
|
||||
}
|
||||
else {
|
||||
var str = Components.classes["@mozilla.org/supports-string;1"]
|
||||
|
|
|
@ -152,7 +152,7 @@ function test() {
|
|||
}
|
||||
}
|
||||
node.containerOpen = false;
|
||||
throw("Unable to find child node");
|
||||
ok(false, "Unable to find child node");
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -318,7 +318,8 @@ function runNextTest() {
|
|||
gBrowser.removeTabsProgressListener(gTabsListener);
|
||||
|
||||
// Restore history.
|
||||
gPrefService.clearUserPref(DISABLE_HISTORY_PREF);
|
||||
if (gPrefService.prefHasUserValue(DISABLE_HISTORY_PREF))
|
||||
gPrefService.clearUserPref(DISABLE_HISTORY_PREF);
|
||||
|
||||
finish();
|
||||
}
|
||||
|
|
|
@ -164,13 +164,6 @@ PrivateBrowsingService.prototype = {
|
|||
}]
|
||||
});
|
||||
|
||||
// whether we should save and close the current session
|
||||
this._saveSession = true;
|
||||
try {
|
||||
if (this._prefs.getBoolPref("browser.privatebrowsing.keep_current_session"))
|
||||
this._saveSession = false;
|
||||
} catch (ex) {}
|
||||
|
||||
if (this._inPrivateBrowsing) {
|
||||
// save the whole browser state in order to restore all windows/tabs later
|
||||
if (this._saveSession && !this._savedBrowserState) {
|
||||
|
@ -310,6 +303,15 @@ PrivateBrowsingService.prototype = {
|
|||
},
|
||||
|
||||
_ensureCanCloseWindows: function PBS__ensureCanCloseWindows() {
|
||||
// whether we should save and close the current session
|
||||
this._saveSession = true;
|
||||
try {
|
||||
if (this._prefs.getBoolPref("browser.privatebrowsing.keep_current_session")) {
|
||||
this._saveSession = false;
|
||||
return;
|
||||
}
|
||||
} catch (ex) {}
|
||||
|
||||
let windowMediator = Cc["@mozilla.org/appshell/window-mediator;1"].
|
||||
getService(Ci.nsIWindowMediator);
|
||||
let windowsEnum = windowMediator.getXULWindowEnumerator("navigator:browser");
|
||||
|
|
|
@ -46,6 +46,7 @@ include $(topsrcdir)/config/rules.mk
|
|||
|
||||
_BROWSER_TEST_FILES = \
|
||||
browser_console_clear.js \
|
||||
browser_privatebrowsing_beforeunload.js \
|
||||
browser_privatebrowsing_certexceptionsui.js \
|
||||
browser_privatebrowsing_crh.js \
|
||||
browser_privatebrowsing_downloadmonitor.js \
|
||||
|
|
|
@ -0,0 +1,247 @@
|
|||
/* ***** 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 Private Browsing Tests.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Nochum Sossonko.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Nochum Sossonko <highmind63@gmail.com> (Original Author)
|
||||
* Ehsan Akhgari <ehsan@mozilla.com>
|
||||
*
|
||||
* 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"),
|
||||
* 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 ***** */
|
||||
|
||||
// This test makes sure that cancelling the unloading of a page with a beforeunload
|
||||
// handler prevents the private browsing mode transition.
|
||||
|
||||
function test() {
|
||||
const kTestPage1 = "data:text/html,<body%20onbeforeunload='return%20false;'>first</body>";
|
||||
const kTestPage2 = "data:text/html,<body%20onbeforeunload='return%20false;'>second</body>";
|
||||
let pb = Cc["@mozilla.org/privatebrowsing;1"]
|
||||
.getService(Ci.nsIPrivateBrowsingService);
|
||||
|
||||
let promptService = {
|
||||
rejectDialog: 0,
|
||||
acceptDialog: 0,
|
||||
confirmCalls: 0,
|
||||
|
||||
alert: function alert(aParent,
|
||||
aDialogTitle,
|
||||
aText) {},
|
||||
|
||||
alertCheck: function alertCheck(aParent,
|
||||
aDialogTitle,
|
||||
aText,
|
||||
aCheckMsg,
|
||||
aCheckState) {},
|
||||
|
||||
confirm: function confirm(aParent,
|
||||
aDialogTitle,
|
||||
aText) {
|
||||
++this.confirmCalls;
|
||||
if (this.acceptDialog-- > 0)
|
||||
return true;
|
||||
else if (this.rejectDialog-- > 0)
|
||||
return false;
|
||||
return true;
|
||||
},
|
||||
|
||||
confirmCheck: function confirmCheck(aParent,
|
||||
aDialogTitle,
|
||||
aText,
|
||||
aCheckMsg,
|
||||
aCheckState) {},
|
||||
|
||||
confirmEx: function confirmEx(aParent,
|
||||
aDialogTitle,
|
||||
aText,
|
||||
aButtonFlags,
|
||||
aButton0Title,
|
||||
aButton1Title,
|
||||
aButton2Title,
|
||||
aCheckMsg,
|
||||
aCheckState) {},
|
||||
|
||||
prompt: function prompt(aParent,
|
||||
aDialogTitle,
|
||||
aText,
|
||||
aValue,
|
||||
aCheckMsg,
|
||||
aCheckState) {},
|
||||
|
||||
promptUsernameAndPassword:
|
||||
function promptUsernameAndPassword(aParent,
|
||||
aDialogTitle,
|
||||
aText,
|
||||
aUsername,
|
||||
aPassword,
|
||||
aCheckMsg,
|
||||
aCheckState) {},
|
||||
|
||||
promptPassword: function promptPassword(aParent,
|
||||
aDialogTitle,
|
||||
aText,
|
||||
aPassword,
|
||||
aCheckMsg,
|
||||
aCheckState) {},
|
||||
|
||||
select: function select(aParent,
|
||||
aDialogTitle,
|
||||
aText,
|
||||
aCount,
|
||||
aSelectList,
|
||||
aOutSelection) {},
|
||||
|
||||
QueryInterface: function QueryInterface(iid) {
|
||||
if (iid.equals(Components.interfaces.nsIPromptService)
|
||||
|| iid.equals(Components.interfaces.nsISupports))
|
||||
return this;
|
||||
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
};
|
||||
|
||||
let PromptServiceFactory = {
|
||||
createInstance: function createInstance(outer, iid) {
|
||||
if (outer != null)
|
||||
throw Components.results.NS_ERROR_NO_AGGREGATION;
|
||||
return promptService.QueryInterface(iid);
|
||||
}
|
||||
};
|
||||
const nsIComponentRegistrar = Components.interfaces.nsIComponentRegistrar;
|
||||
let registrar = Components.manager.QueryInterface(nsIComponentRegistrar);
|
||||
const psID = Components.ID("{6cc9c9fe-bc0b-432b-a410-253ef8bcc699}");
|
||||
registrar.registerFactory(psID,
|
||||
"PromptService",
|
||||
"@mozilla.org/embedcomp/prompt-service;1",
|
||||
PromptServiceFactory);
|
||||
|
||||
waitForExplicitFinish();
|
||||
let browser1 = gBrowser.getBrowserForTab(gBrowser.addTab());
|
||||
browser1.addEventListener("load", function() {
|
||||
browser1.removeEventListener("load", arguments.callee, true);
|
||||
|
||||
let browser2 = gBrowser.getBrowserForTab(gBrowser.addTab());
|
||||
browser2.addEventListener("load", function() {
|
||||
browser2.removeEventListener("load", arguments.callee, true);
|
||||
|
||||
promptService.rejectDialog = 1;
|
||||
pb.privateBrowsingEnabled = true;
|
||||
|
||||
ok(!pb.privateBrowsingEnabled, "Private browsing mode should not have been activated");
|
||||
is(promptService.confirmCalls, 1, "Only one confirm box should be shown");
|
||||
is(gBrowser.tabContainer.childNodes.length, 3,
|
||||
"No tabs should be closed because private browsing mode transition was canceled");
|
||||
is(gBrowser.getBrowserForTab(gBrowser.tabContainer.firstChild).currentURI.spec, "about:blank",
|
||||
"The first tab should be a blank tab");
|
||||
is(gBrowser.getBrowserForTab(gBrowser.tabContainer.firstChild.nextSibling).currentURI.spec, kTestPage1,
|
||||
"The middle tab should be the same one we opened");
|
||||
is(gBrowser.getBrowserForTab(gBrowser.tabContainer.lastChild).currentURI.spec, kTestPage2,
|
||||
"The last tab should be the same one we opened");
|
||||
is(promptService.rejectDialog, 0, "Only one confirm dialog should have been rejected");
|
||||
|
||||
promptService.confirmCalls = 0;
|
||||
promptService.acceptDialog = 2;
|
||||
pb.privateBrowsingEnabled = true;
|
||||
|
||||
ok(pb.privateBrowsingEnabled, "Private browsing mode should have been activated");
|
||||
is(promptService.confirmCalls, 2, "Only two confirm boxes should be shown");
|
||||
is(gBrowser.tabContainer.childNodes.length, 1,
|
||||
"Incorrect number of tabs after transition into private browsing");
|
||||
gBrowser.selectedBrowser.addEventListener("load", function() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
|
||||
|
||||
is(gBrowser.selectedBrowser.currentURI.spec, "about:privatebrowsing",
|
||||
"Incorrect page displayed after private browsing transition");
|
||||
is(promptService.acceptDialog, 0, "Two confirm dialogs should have been accepted");
|
||||
|
||||
gBrowser.selectedBrowser.addEventListener("load", function() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
|
||||
|
||||
promptService.confirmCalls = 0;
|
||||
promptService.rejectDialog = 1;
|
||||
pb.privateBrowsingEnabled = false;
|
||||
|
||||
ok(pb.privateBrowsingEnabled, "Private browsing mode should not have been deactivated");
|
||||
is(promptService.confirmCalls, 1, "Only one confirm box should be shown");
|
||||
is(gBrowser.tabContainer.childNodes.length, 2,
|
||||
"No tabs should be closed because private browsing mode transition was canceled");
|
||||
is(gBrowser.getBrowserForTab(gBrowser.tabContainer.firstChild).currentURI.spec, kTestPage1,
|
||||
"The first tab should be the same one we opened");
|
||||
is(gBrowser.getBrowserForTab(gBrowser.tabContainer.lastChild).currentURI.spec, kTestPage2,
|
||||
"The last tab should be the same one we opened");
|
||||
is(promptService.rejectDialog, 0, "Only one confirm dialog should have been rejected");
|
||||
|
||||
promptService.confirmCalls = 0;
|
||||
promptService.acceptDialog = 2;
|
||||
pb.privateBrowsingEnabled = false;
|
||||
|
||||
ok(!pb.privateBrowsingEnabled, "Private browsing mode should have been deactivated");
|
||||
is(promptService.confirmCalls, 2, "Only two confirm boxes should be shown");
|
||||
is(gBrowser.tabContainer.childNodes.length, 3,
|
||||
"Incorrect number of tabs after transition into private browsing");
|
||||
|
||||
let loads = 0;
|
||||
function waitForLoad(event) {
|
||||
gBrowser.removeEventListener("load", arguments.callee, true);
|
||||
|
||||
if (++loads != 3)
|
||||
return;
|
||||
|
||||
is(gBrowser.getBrowserForTab(gBrowser.tabContainer.firstChild).currentURI.spec, "about:blank",
|
||||
"The first tab should be a blank tab");
|
||||
is(gBrowser.getBrowserForTab(gBrowser.tabContainer.firstChild.nextSibling).currentURI.spec, kTestPage1,
|
||||
"The middle tab should be the same one we opened");
|
||||
is(gBrowser.getBrowserForTab(gBrowser.tabContainer.lastChild).currentURI.spec, kTestPage2,
|
||||
"The last tab should be the same one we opened");
|
||||
is(promptService.acceptDialog, 0, "Two confirm dialogs should have been accepted");
|
||||
is(promptService.acceptDialog, 0, "Two prompts should have been raised");
|
||||
|
||||
promptService.acceptDialog = 2;
|
||||
gBrowser.removeTab(gBrowser.tabContainer.lastChild);
|
||||
gBrowser.removeTab(gBrowser.tabContainer.lastChild);
|
||||
|
||||
registrar.unregisterFactory(psID, PromptServiceFactory);
|
||||
finish();
|
||||
}
|
||||
for (let i = 0; i < gBrowser.browsers.length; ++i)
|
||||
gBrowser.browsers[i].addEventListener("load", waitForLoad, true);
|
||||
}, true);
|
||||
gBrowser.selectedBrowser.loadURI(kTestPage2);
|
||||
}, true);
|
||||
gBrowser.selectedBrowser.loadURI(kTestPage1);
|
||||
}, true);
|
||||
}, true);
|
||||
browser2.loadURI(kTestPage2);
|
||||
}, true);
|
||||
browser1.loadURI(kTestPage1);
|
||||
}
|
|
@ -54,7 +54,8 @@ function test() {
|
|||
|
||||
function setupCleanSlate() {
|
||||
gLastOpenDirectory.reset();
|
||||
gPrefService.clearUserPref(kPrefName);
|
||||
if (gPrefService.prefHasUserValue(kPrefName))
|
||||
gPrefService.clearUserPref(kPrefName);
|
||||
}
|
||||
|
||||
setupCleanSlate();
|
||||
|
|
|
@ -88,7 +88,9 @@ function test() {
|
|||
"chrome,titlebar", window);
|
||||
}
|
||||
|
||||
gPrefService.clearUserPref("general.open_location.last_url");
|
||||
|
||||
if (gPrefService.prefHasUserValue("general.open_location.last_url"))
|
||||
gPrefService.clearUserPref("general.open_location.last_url");
|
||||
|
||||
openLocation("http://example.com/", "", function() {
|
||||
openLocation("http://example.org/", "http://example.com/", function() {
|
||||
|
@ -100,7 +102,8 @@ function test() {
|
|||
pb.privateBrowsingEnabled = false;
|
||||
openLocation("about:blank", "http://example.org/", function() {
|
||||
gPrefService.clearUserPref("general.open_location.last_url");
|
||||
gPrefService.clearUserPref("general.open_location.last_window_choice");
|
||||
if (gPrefService.prefHasUserValue("general.open_location.last_window_choice"))
|
||||
gPrefService.clearUserPref("general.open_location.last_window_choice");
|
||||
finish();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1555,7 +1555,7 @@ SessionStoreService.prototype = {
|
|||
if (node.type != "file")
|
||||
data[id] = node.type == "checkbox" || node.type == "radio" ? node.checked : node.value;
|
||||
else
|
||||
data[id] = { type: "file", fileList: node.mozGetFileNameArray({}) };
|
||||
data[id] = { type: "file", fileList: node.mozGetFileNameArray() };
|
||||
}
|
||||
else if (node instanceof Ci.nsIDOMHTMLTextAreaElement)
|
||||
data[id] = node.value;
|
||||
|
|
|
@ -135,7 +135,8 @@ function test() {
|
|||
gBrowser.removeTab(tab_A);
|
||||
|
||||
// record the timestamp of sessionstore.js at the end of the private session
|
||||
gPrefService.clearUserPref("browser.sessionstore.interval");
|
||||
if (gPrefService.prefHasUserValue("browser.sessionstore.interval"))
|
||||
gPrefService.clearUserPref("browser.sessionstore.interval");
|
||||
gPrefService.setIntPref("browser.sessionstore.interval", 0);
|
||||
let endPBModeTimeStamp = getSessionstorejsModificationTime();
|
||||
|
||||
|
|
|
@ -129,7 +129,7 @@ function test() {
|
|||
let state = { entries: [{ url: testURL }], extData: { key: value } };
|
||||
|
||||
// public session, add new tab: (A)
|
||||
tab_A = gBrowser.addTab(testURL);
|
||||
let tab_A = gBrowser.addTab(testURL);
|
||||
ss.setTabState(tab_A, state.toSource());
|
||||
tab_A.linkedBrowser.addEventListener("load", function(aEvent) {
|
||||
this.removeEventListener("load", arguments.callee, true);
|
||||
|
@ -166,7 +166,7 @@ function test() {
|
|||
let state1 = { entries: [{ url: testURL2 }], extData: { key1: value1 } };
|
||||
|
||||
// private browsing session, new tab: (B)
|
||||
tab_B = gBrowser.addTab(testURL2);
|
||||
let tab_B = gBrowser.addTab(testURL2);
|
||||
ss.setTabState(tab_B, state1.toSource());
|
||||
tab_B.linkedBrowser.addEventListener("load", function(aEvent) {
|
||||
this.removeEventListener("load", arguments.callee, true);
|
||||
|
@ -197,7 +197,8 @@ function test() {
|
|||
ok(!pb.privateBrowsingEnabled, "private browsing disabled");
|
||||
|
||||
// cleanup
|
||||
gPrefService.clearUserPref("browser.privatebrowsing.keep_current_session");
|
||||
if (gPrefService.prefHasUserValue("browser.privatebrowsing.keep_current_session"))
|
||||
gPrefService.clearUserPref("browser.privatebrowsing.keep_current_session");
|
||||
finish();
|
||||
}, true);
|
||||
}, true);
|
||||
|
|
|
@ -82,7 +82,7 @@ function test() {
|
|||
return false;
|
||||
if (node instanceof Ci.nsIDOMHTMLInputElement) {
|
||||
if (node.type == "file") {
|
||||
let fileNames = node.mozGetFileNameArray({});
|
||||
let fileNames = node.mozGetFileNameArray();
|
||||
return fileNames.length == aValue.length &&
|
||||
Array.every(fileNames, function(aFile) aValue.indexOf(aFile) >= 0);
|
||||
}
|
||||
|
@ -131,7 +131,8 @@ function test() {
|
|||
ok(!compareFormValue(tab, xpath, fieldList[xpath]),
|
||||
"The value for \"" + xpath + "\" was correctly discarded");
|
||||
|
||||
gPrefService.clearUserPref("browser.sessionstore.privacy_level");
|
||||
if (gPrefService.prefHasUserValue("browser.sessionstore.privacy_level"))
|
||||
gPrefService.clearUserPref("browser.sessionstore.privacy_level");
|
||||
// undoCloseTab can reuse a single blank tab, so we have to
|
||||
// make sure not to close the window when closing our last tab
|
||||
if (tabbrowser.tabContainer.childNodes.length == 1)
|
||||
|
|
|
@ -95,7 +95,8 @@ function test() {
|
|||
is(this.currentURI.spec, testURL, "correct tab was reopened");
|
||||
|
||||
// clean up
|
||||
gPrefService.clearUserPref("browser.sessionstore.max_tabs_undo");
|
||||
if (gPrefService.prefHasUserValue("browser.sessionstore.max_tabs_undo"))
|
||||
gPrefService.clearUserPref("browser.sessionstore.max_tabs_undo");
|
||||
tabbrowser.removeTab(tab);
|
||||
finish();
|
||||
}, true);
|
||||
|
|
|
@ -65,7 +65,8 @@ function test() {
|
|||
"The closed blank tab wasn't added to Recently Closed Tabs");
|
||||
|
||||
// clean up
|
||||
gPrefService.clearUserPref("browser.sessionstore.max_tabs_undo");
|
||||
if (gPrefService.prefHasUserValue("browser.sessionstore.max_tabs_undo"))
|
||||
gPrefService.clearUserPref("browser.sessionstore.max_tabs_undo");
|
||||
finish();
|
||||
}, true);
|
||||
}, true);
|
||||
|
|
|
@ -104,7 +104,8 @@ function test() {
|
|||
|
||||
// clean up
|
||||
newWin2.close();
|
||||
gPrefService.clearUserPref("browser.sessionstore.max_windows_undo");
|
||||
if (gPrefService.prefHasUserValue("browser.sessionstore.max_windows_undo"))
|
||||
gPrefService.clearUserPref("browser.sessionstore.max_windows_undo");
|
||||
executeSoon(callback);
|
||||
}, true);
|
||||
}, false);
|
||||
|
|
|
@ -42,13 +42,8 @@ function test() {
|
|||
|
||||
waitForExplicitFinish();
|
||||
|
||||
// Setup.
|
||||
let pb = Cc["@mozilla.org/privatebrowsing;1"].
|
||||
getService(Ci.nsIPrivateBrowsingService);
|
||||
let ss = Cc["@mozilla.org/browser/sessionstore;1"].
|
||||
getService(Ci.nsISessionStore);
|
||||
let ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
|
||||
getService(Ci.nsIWindowWatcher);
|
||||
|
||||
// Remove the sessionstore.js file before setting the interval to 0
|
||||
let profilePath = Cc["@mozilla.org/file/directory_service;1"].
|
||||
|
@ -60,12 +55,31 @@ function test() {
|
|||
sessionStoreJS.remove(false);
|
||||
ok(sessionStoreJS.exists() == false, "sessionstore.js was removed");
|
||||
// Make sure that sessionstore.js can be forced to be created by setting
|
||||
// the interval pref to 0
|
||||
gPrefService.setIntPref("browser.sessionstore.interval", 0);
|
||||
// the interval pref to a low value.
|
||||
gPrefService.setIntPref("browser.sessionstore.interval", 100);
|
||||
// sessionstore.js should be re-created at this point
|
||||
sessionStoreJS = profilePath.clone();
|
||||
sessionStoreJS.append("sessionstore.js");
|
||||
|
||||
// Wait for the sessionstore.js file to be written before going on.
|
||||
let os = Cc["@mozilla.org/observer-service;1"].
|
||||
getService(Ci.nsIObserverService);
|
||||
os.addObserver({observe: function(aSubject, aTopic, aData) {
|
||||
if (gPrefService.prefHasUserValue("browser.sessionstore.interval"))
|
||||
gPrefService.clearUserPref("browser.sessionstore.interval");
|
||||
os.removeObserver(this, aTopic);
|
||||
executeSoon(continue_test);
|
||||
}}, "sessionstore-state-write-complete", false);
|
||||
|
||||
//XXXDEBUG Detect spurious windows-restored notifications.
|
||||
os.addObserver({observe: function(aSubject, aTopic, aData) {
|
||||
// If this is not called in this test it will be called by next ones,
|
||||
// but i don't mind actually, it's just an info(), and will go away once
|
||||
// the randomness has been fixed.
|
||||
info("Windows status has been restored, was that expected?");
|
||||
os.removeObserver(this, aTopic);
|
||||
}}, "sessionstore-windows-restored", false);
|
||||
|
||||
// Set up the browser in a blank state. Popup windows in previous tests result
|
||||
// in different states on different platforms.
|
||||
let blankState = JSON.stringify({
|
||||
|
@ -76,28 +90,36 @@ function test() {
|
|||
_closedWindows: []
|
||||
});
|
||||
ss.setBrowserState(blankState);
|
||||
}
|
||||
|
||||
function continue_test() {
|
||||
let ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
|
||||
getService(Ci.nsIWindowWatcher);
|
||||
let pb = Cc["@mozilla.org/privatebrowsing;1"].
|
||||
getService(Ci.nsIPrivateBrowsingService);
|
||||
let ss = Cc["@mozilla.org/browser/sessionstore;1"].
|
||||
getService(Ci.nsISessionStore);
|
||||
|
||||
let closedWindowCount = ss.getClosedWindowCount();
|
||||
is(closedWindowCount, 0, "Correctly set window count");
|
||||
|
||||
// Prevent VM timers issues, cache now and increment it manually.
|
||||
const NOW = Date.now();
|
||||
|
||||
let now = Date.now();
|
||||
const TESTS = [
|
||||
{ url: "about:config",
|
||||
key: "bug 394759 Non-PB",
|
||||
value: "uniq" + (++NOW) },
|
||||
value: "uniq" + (++now) },
|
||||
{ url: "about:mozilla",
|
||||
key: "bug 394759 PB",
|
||||
value: "uniq" + (++NOW) },
|
||||
value: "uniq" + (++now) },
|
||||
];
|
||||
|
||||
let loadWasCalled = false;
|
||||
function openWindowAndTest(aTestIndex, aRunNextTestInPBMode) {
|
||||
info("Opening new window");
|
||||
let windowObserver = {
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
if (aTopic === "domwindowopened") {
|
||||
ww.unregisterNotification(this);
|
||||
info("New window has been opened");
|
||||
let win = aSubject.QueryInterface(Ci.nsIDOMWindow);
|
||||
win.addEventListener("load", function onLoad(event) {
|
||||
|
@ -106,6 +128,7 @@ function test() {
|
|||
win.gBrowser.addEventListener("load", function(aEvent) {
|
||||
win.gBrowser.removeEventListener("load", arguments.callee, true);
|
||||
info("New window browser has been loaded");
|
||||
loadWasCalled = true;
|
||||
executeSoon(function() {
|
||||
// Add a tab.
|
||||
win.gBrowser.addTab();
|
||||
|
@ -147,16 +170,13 @@ function test() {
|
|||
"when exiting PB mode");
|
||||
|
||||
let data = JSON.parse(ss.getClosedWindowData())[0];
|
||||
ok(data.toSource().indexOf(TESTS[aTestIndex].value) > -1,
|
||||
ok(data.toSource().indexOf(TESTS[aTestIndex - 1].value) > -1,
|
||||
"The data associated with the recently closed window was " +
|
||||
"restored when exiting PB mode");
|
||||
}
|
||||
|
||||
if (aTestIndex == TESTS.length - 1) {
|
||||
// Cleanup and finish.
|
||||
gPrefService.clearUserPref("browser.sessionstore.interval");
|
||||
if (aTestIndex == TESTS.length - 1)
|
||||
finish();
|
||||
}
|
||||
else {
|
||||
// Run next test.
|
||||
openWindowAndTest(aTestIndex + 1, !aRunNextTestInPBMode);
|
||||
|
@ -166,6 +186,14 @@ function test() {
|
|||
}, true);
|
||||
}, false);
|
||||
}
|
||||
else if (aTopic === "domwindowclosed") {
|
||||
info("Window closed");
|
||||
ww.unregisterNotification(this);
|
||||
if (!loadWasCalled) {
|
||||
ok(false, "Window was closed before load could fire!");
|
||||
finish();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
ww.registerNotification(windowObserver);
|
||||
|
|
|
@ -97,7 +97,8 @@ function test() {
|
|||
is(cookie.path, cookie2.path, "cookie path successfully restored");
|
||||
|
||||
// clean up
|
||||
gPrefService.clearUserPref("browser.sessionstore.interval");
|
||||
if (gPrefService.prefHasUserValue("browser.sessionstore.interval"))
|
||||
gPrefService.clearUserPref("browser.sessionstore.interval");
|
||||
cs.removeAll();
|
||||
newWin.close();
|
||||
finish();
|
||||
|
|
|
@ -86,7 +86,8 @@ function test() {
|
|||
// clean up
|
||||
gBrowser.removeTab(tab);
|
||||
os.removeObserver(this, aTopic, false);
|
||||
gPrefService.clearUserPref("browser.sessionstore.interval");
|
||||
if (gPrefService.prefHasUserValue("browser.sessionstore.interval"))
|
||||
gPrefService.clearUserPref("browser.sessionstore.interval");
|
||||
finish();
|
||||
}
|
||||
};
|
||||
|
|
|
@ -71,7 +71,8 @@ function test() {
|
|||
}
|
||||
|
||||
// clean up
|
||||
gPrefService.clearUserPref("browser.sessionstore.privacy_level");
|
||||
if (gPrefService.prefHasUserValue("browser.sessionstore.privacy_level"))
|
||||
gPrefService.clearUserPref("browser.sessionstore.privacy_level");
|
||||
// undoCloseTab can reuse a single blank tab, so we have to
|
||||
// make sure not to close the window when closing our last tab
|
||||
if (gBrowser.tabContainer.childNodes.length == 1)
|
||||
|
|
|
@ -66,7 +66,8 @@ function test() {
|
|||
is(countBad, 0, "Didn't save text for ignored field types");
|
||||
|
||||
// clean up
|
||||
gPrefService.clearUserPref("browser.sessionstore.privacy_level");
|
||||
if (gPrefService.prefHasUserValue("browser.sessionstore.privacy_level"))
|
||||
gPrefService.clearUserPref("browser.sessionstore.privacy_level");
|
||||
finish();
|
||||
}, true);
|
||||
}
|
||||
|
|
|
@ -62,11 +62,14 @@ function test() {
|
|||
return;
|
||||
this.removeEventListener("load", arguments.callee, true);
|
||||
|
||||
let maxWait = Date.now() + 1000;
|
||||
let pass = 0;
|
||||
const MAX_PASS = 6;
|
||||
executeSoon(function() {
|
||||
info("Checking innerHTML, pass: " + (pass + 1));
|
||||
let iframes = tab2.linkedBrowser.contentWindow.frames;
|
||||
if (iframes[1].document.body.innerHTML != uniqueValue && Date.now() < maxWait) {
|
||||
executeSoon(arguments.callee);
|
||||
if (iframes[1].document.body.innerHTML != uniqueValue &&
|
||||
++pass <= MAX_PASS) {
|
||||
setTimeout(arguments.callee, 500);
|
||||
return;
|
||||
}
|
||||
is(iframes[1].document.body.innerHTML, uniqueValue,
|
||||
|
|
|
@ -43,10 +43,13 @@ function test() {
|
|||
"browser/components/sessionstore/test/browser/browser_461743_sample.html";
|
||||
|
||||
let tab = gBrowser.addTab(testURL);
|
||||
info("New tab added");
|
||||
tab.linkedBrowser.addEventListener("load", function(aEvent) {
|
||||
info("New tab loaded");
|
||||
this.removeEventListener("load", arguments.callee, true);
|
||||
executeSoon(function() {
|
||||
let tab2 = gBrowser.duplicateTab(tab);
|
||||
info("Duplicated tab");
|
||||
tab2.linkedBrowser.addEventListener("461743", function(aEvent) {
|
||||
tab2.linkedBrowser.removeEventListener("461743", arguments.callee, true);
|
||||
is(aEvent.data, "done", "XSS injection was attempted");
|
||||
|
|
|
@ -103,7 +103,8 @@ function test() {
|
|||
|
||||
// clean up
|
||||
newWin.close();
|
||||
gPrefService.clearUserPref("browser.sessionstore.max_tabs_undo");
|
||||
if (gPrefService.prefHasUserValue("browser.sessionstore.max_tabs_undo"))
|
||||
gPrefService.clearUserPref("browser.sessionstore.max_tabs_undo");
|
||||
finish();
|
||||
}, false);
|
||||
}
|
||||
|
|
|
@ -77,7 +77,10 @@ function test() {
|
|||
|
||||
// close tab, restore default values and finish the test
|
||||
gBrowser.removeTab(tab);
|
||||
gPrefService.clearUserPref("browser.startup.page");
|
||||
// we need this if-statement because if there is no user set value,
|
||||
// clearUserPref throws a uncatched exception and finish is not called
|
||||
if (gPrefService.prefHasUserValue("browser.startup.page"))
|
||||
gPrefService.clearUserPref("browser.startup.page");
|
||||
gPrefService.clearUserPref("browser.startup.homepage");
|
||||
finish();
|
||||
}, true);
|
||||
|
|
|
@ -152,7 +152,8 @@ function test() {
|
|||
testWithState(state);
|
||||
}
|
||||
else {
|
||||
gPrefService.clearUserPref("browser.sessionstore.max_windows_undo");
|
||||
if (gPrefService.prefHasUserValue("browser.sessionstore.max_windows_undo"))
|
||||
gPrefService.clearUserPref("browser.sessionstore.max_windows_undo");
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -149,7 +149,8 @@ function test() {
|
|||
|
||||
// clean up
|
||||
newWin.close();
|
||||
gPrefService.clearUserPref("browser.sessionstore.max_windows_undo");
|
||||
if (gPrefService.prefHasUserValue("browser.sessionstore.max_windows_undo"))
|
||||
gPrefService.clearUserPref("browser.sessionstore.max_windows_undo");
|
||||
finish();
|
||||
}, false);
|
||||
}
|
||||
|
|
|
@ -73,7 +73,7 @@ function test() {
|
|||
"URL bar autocomplete state should be restored correctly");
|
||||
|
||||
win.close();
|
||||
callback();
|
||||
executeSoon(callback);
|
||||
}, false);
|
||||
}
|
||||
|
||||
|
|
|
@ -94,7 +94,8 @@ function test() {
|
|||
getPreviewForTab(gBrowser.mTabs[1]).controller.onClose();
|
||||
checkPreviews(1);
|
||||
|
||||
gPrefService.clearUserPref(ENABLE_PREF_NAME);
|
||||
if (gPrefService.prefHasUserValue(ENABLE_PREF_NAME))
|
||||
gPrefService.clearUserPref(ENABLE_PREF_NAME);
|
||||
|
||||
finish();
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
<!ENTITY helpReleaseNotes.label "Release Notes">
|
||||
<!ENTITY helpReleaseNotes.accesskey "N">
|
||||
|
||||
<!ENTITY helpTroubleshooting.label "Troubleshooting Information…">
|
||||
<!ENTITY helpTroubleshooting.label "Troubleshooting Information">
|
||||
<!ENTITY helpTroubleshooting.accesskey "T">
|
||||
|
||||
<!ENTITY updateCmd.label "Check for Updates…">
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
repo: f5ab154deef2ffa97f1b2139589ae4a1962090a4
|
||||
node: 0aa14be496b38ea56b28158f375d01dc0cb91d1f
|
||||
node: 3476582628db128ad061c30cab1a74a0c5d14b9b
|
||||
|
|
|
@ -1008,7 +1008,7 @@ class Target(object):
|
|||
makefile.context.defer(cb, error=self.error, didanything=self.didanything)
|
||||
del self._callbacks
|
||||
|
||||
def make(self, makefile, targetstack, cb, avoidremakeloop=False):
|
||||
def make(self, makefile, targetstack, cb, avoidremakeloop=False, printerror=True):
|
||||
"""
|
||||
If we are out of date, asynchronously make ourself. This is a multi-stage process, mostly handled
|
||||
by the helper objects RemakeTargetSerially, RemakeTargetParallel,
|
||||
|
@ -1051,7 +1051,8 @@ class Target(object):
|
|||
try:
|
||||
self.resolvedeps(makefile, targetstack, [], False)
|
||||
except util.MakeError, e:
|
||||
print e
|
||||
if printerror:
|
||||
print e
|
||||
self.error = True
|
||||
self.notifydone(makefile)
|
||||
return
|
||||
|
@ -1312,7 +1313,7 @@ class _RemakeContext(object):
|
|||
|
||||
if len(self.toremake):
|
||||
target, self.required = self.toremake.pop(0)
|
||||
target.make(self.makefile, [], avoidremakeloop=True, cb=self.remakecb)
|
||||
target.make(self.makefile, [], avoidremakeloop=True, cb=self.remakecb, printerror=False)
|
||||
else:
|
||||
for t, required in self.included:
|
||||
if t.wasremade:
|
||||
|
|
|
@ -71,7 +71,7 @@ class Data(object):
|
|||
"""
|
||||
m = _skipws.search(self.s, offset, self.lend)
|
||||
if m is None:
|
||||
return None
|
||||
return self.lend
|
||||
|
||||
return m.start(0)
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ import os
|
|||
|
||||
class MakeError(Exception):
|
||||
def __init__(self, message, loc=None):
|
||||
self.message = message
|
||||
self.msg = message
|
||||
self.loc = loc
|
||||
|
||||
def __str__(self):
|
||||
|
@ -10,7 +10,7 @@ class MakeError(Exception):
|
|||
if self.loc is not None:
|
||||
locstr = "%s:" % (self.loc,)
|
||||
|
||||
return "%s%s" % (locstr, self.message)
|
||||
return "%s%s" % (locstr, self.msg)
|
||||
|
||||
def joiniter(fd, it):
|
||||
"""
|
||||
|
@ -32,6 +32,8 @@ def checkmsyscompat():
|
|||
letting Python use the system shell."""
|
||||
if 'SHELL' in os.environ:
|
||||
shell = os.environ['SHELL']
|
||||
elif 'MOZILLABUILD' in os.environ:
|
||||
shell = os.environ['MOZILLABUILD'] + '/msys/bin/sh.exe'
|
||||
elif 'COMSPEC' in os.environ:
|
||||
shell = os.environ['COMSPEC']
|
||||
else:
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
all:
|
||||
@echo TEST-PASS
|
||||
|
||||
foo: ;
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
-include TEST-FAIL.mk
|
||||
|
||||
all:
|
||||
@echo TEST-PASS
|
|
@ -73,7 +73,7 @@ while (<>) {
|
|||
my @deps = split /\s+/, $rest;
|
||||
push @{$alldeps{$obj}}, @deps;
|
||||
if (DEBUG >= 2) {
|
||||
foreach my $dep (@deps) { print "add $obj $dep\n"; }
|
||||
foreach my $dep (@deps) { print STDERR "add $obj $dep\n"; }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,21 +88,21 @@ OBJ_LOOP: foreach my $obj (keys %alldeps) {
|
|||
foreach my $dep_file (@{$deps}) {
|
||||
my $dep_mtime = $modtimes{$dep_file};
|
||||
if (not defined $dep_mtime) {
|
||||
print "Skipping $dep_file for $obj, will stat() later\n" if DEBUG >= 2;
|
||||
print STDERR "Skipping $dep_file for $obj, will stat() later\n" if DEBUG >= 2;
|
||||
$not_in_cache{$dep_file} = 1;
|
||||
next;
|
||||
}
|
||||
|
||||
print "Found $dep_file in cache\n" if DEBUG >= 2;
|
||||
print STDERR "Found $dep_file in cache\n" if DEBUG >= 2;
|
||||
|
||||
if ($dep_mtime > $mtime) {
|
||||
print "$dep_file($dep_mtime) newer than $obj($mtime)\n" if DEBUG;
|
||||
print STDERR "$dep_file($dep_mtime) newer than $obj($mtime)\n" if DEBUG;
|
||||
}
|
||||
elsif ($dep_mtime == -1) {
|
||||
print "Couldn't stat $dep_file for $obj\n" if DEBUG;
|
||||
print STDERR "Couldn't stat $dep_file for $obj\n" if DEBUG;
|
||||
}
|
||||
else {
|
||||
print "$dep_file($dep_mtime) older than $obj($mtime)\n" if DEBUG >= 2;
|
||||
print STDERR "$dep_file($dep_mtime) older than $obj($mtime)\n" if DEBUG >= 2;
|
||||
next;
|
||||
}
|
||||
|
||||
|
@ -111,17 +111,17 @@ OBJ_LOOP: foreach my $obj (keys %alldeps) {
|
|||
}
|
||||
|
||||
foreach my $dep_file (keys %not_in_cache) {
|
||||
print "STAT $dep_file for $obj\n" if DEBUG >= 2;
|
||||
print STDERR "STAT $dep_file for $obj\n" if DEBUG >= 2;
|
||||
my $dep_mtime = $modtimes{$dep_file} = (stat $dep_file)[9] || -1;
|
||||
|
||||
if ($dep_mtime > $mtime) {
|
||||
print "$dep_file($dep_mtime) newer than $obj($mtime)\n" if DEBUG;
|
||||
print STDERR "$dep_file($dep_mtime) newer than $obj($mtime)\n" if DEBUG;
|
||||
}
|
||||
elsif ($dep_mtime == -1) {
|
||||
print "Couldn't stat $dep_file for $obj\n" if DEBUG;
|
||||
print STDERR "Couldn't stat $dep_file for $obj\n" if DEBUG;
|
||||
}
|
||||
else {
|
||||
print "$dep_file($dep_mtime) older than $obj($mtime)\n" if DEBUG >= 2;
|
||||
print STDERR "$dep_file($dep_mtime) older than $obj($mtime)\n" if DEBUG >= 2;
|
||||
next;
|
||||
}
|
||||
|
||||
|
@ -133,7 +133,11 @@ OBJ_LOOP: foreach my $obj (keys %alldeps) {
|
|||
}
|
||||
|
||||
# Output objects to rebuild (if needed).
|
||||
if (@objs) {
|
||||
if ($outfile eq '-') {
|
||||
if (@objs) {
|
||||
print "@objs: FORCE\n";
|
||||
}
|
||||
} elsif (@objs) {
|
||||
my $old_output;
|
||||
my $new_output = "@objs: FORCE\n";
|
||||
|
||||
|
|
|
@ -250,6 +250,7 @@ class JarMaker(object):
|
|||
that against the l10nbases. l10nbases can either be path strings, or
|
||||
callables. In the latter case, that will be called with the
|
||||
relativesrcdir as argument, and is expected to return a path string.
|
||||
This logic is disabled if the jar.mn path is not inside the topsrcdir.
|
||||
'''
|
||||
topsourcedir = os.path.normpath(os.path.abspath(topsourcedir))
|
||||
def resolveL10nBase(relpath):
|
||||
|
@ -265,13 +266,18 @@ class JarMaker(object):
|
|||
l10ndir = srcdir
|
||||
if os.path.basename(srcdir) == 'locales':
|
||||
l10ndir = os.path.dirname(l10ndir)
|
||||
assert srcdir.startswith(topsourcedir), "src dir %s not in topsourcedir %s" % (srcdir, topsourcedir)
|
||||
rell10ndir = l10ndir[len(topsourcedir):].lstrip(os.sep)
|
||||
|
||||
l10ndirs = map(resolveL10nBase(rell10ndir), l10nbases)
|
||||
if localedirs is not None:
|
||||
l10ndirs += [os.path.normpath(os.path.abspath(s))
|
||||
for s in localedirs]
|
||||
|
||||
l10ndirs = None
|
||||
# srcdir may not be a child of topsourcedir, in which case
|
||||
# we assume that the caller passed in suitable sourcedirs,
|
||||
# and just skip passing in localedirs
|
||||
if srcdir.startswith(topsourcedir):
|
||||
rell10ndir = l10ndir[len(topsourcedir):].lstrip(os.sep)
|
||||
|
||||
l10ndirs = map(resolveL10nBase(rell10ndir), l10nbases)
|
||||
if localedirs is not None:
|
||||
l10ndirs += [os.path.normpath(os.path.abspath(s))
|
||||
for s in localedirs]
|
||||
srcdirs = [os.path.normpath(os.path.abspath(s))
|
||||
for s in sourcedirs] + [srcdir]
|
||||
self.makeJar(infile=infile,
|
||||
|
@ -375,7 +381,7 @@ class JarMaker(object):
|
|||
if realsrc is None:
|
||||
if jf is not None:
|
||||
jf.close()
|
||||
raise RuntimeError("file not found: " + src)
|
||||
raise RuntimeError('File "%s" not found in %s' % (src, ', '.join(src_base)))
|
||||
if m.group('optPreprocess'):
|
||||
outf = outHelper.getOutput(out)
|
||||
inf = open(realsrc)
|
||||
|
|
|
@ -157,8 +157,13 @@ clean clobber realclean clobber_all::
|
|||
cd $(MKDEPEND_DIR); $(MAKE) $@
|
||||
endif
|
||||
|
||||
PYUNITS := unit-Expression.py unit-Preprocessor.py unit-nsinstall.py \
|
||||
unit-printprereleasesuffix.py
|
||||
PYUNITS := \
|
||||
unit-Expression.py \
|
||||
unit-Preprocessor.py \
|
||||
unit-nsinstall.py \
|
||||
unit-printprereleasesuffix.py \
|
||||
unit-JarMaker.py \
|
||||
$(NULL)
|
||||
|
||||
check:: check-python-modules check-jar-mn
|
||||
|
||||
|
|
|
@ -167,6 +167,7 @@ MOZ_CRASHREPORTER = @MOZ_CRASHREPORTER@
|
|||
MOZ_HELP_VIEWER = @MOZ_HELP_VIEWER@
|
||||
MOC= @MOC@
|
||||
MOZ_NSS_PATCH = @MOZ_NSS_PATCH@
|
||||
MOZ_WEBGL = @MOZ_WEBGL@
|
||||
|
||||
MOZ_JAVAXPCOM = @MOZ_JAVAXPCOM@
|
||||
JAVA_INCLUDE_PATH="@JAVA_INCLUDE_PATH@"
|
||||
|
|
|
@ -772,11 +772,6 @@ endif # absolute_symlink
|
|||
endif # copy
|
||||
endif # WINNT/OS2
|
||||
|
||||
ifeq (,$(filter-out WINCE,$(OS_ARCH)))
|
||||
NSINSTALL = $(CYGWIN_WRAPPER) nsinstall
|
||||
INSTALL = $(CYGWIN_WRAPPER) nsinstall
|
||||
endif
|
||||
|
||||
# Use nsinstall in copy mode to install files on the system
|
||||
SYSINSTALL = $(NSINSTALL) -t
|
||||
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
from unittest import TextTestRunner as _TestRunner, TestResult as _TestResult
|
||||
import inspect
|
||||
|
||||
'''Helper to make python unit tests report the way that the Mozilla
|
||||
unit test infrastructure expects tests to report.
|
||||
|
||||
Usage:
|
||||
|
||||
import unittest
|
||||
from mozunit import MozTestRunner
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(testRunner=MozTestRunner())
|
||||
'''
|
||||
|
||||
class _MozTestResult(_TestResult):
|
||||
def __init__(self, stream, descriptions):
|
||||
_TestResult.__init__(self)
|
||||
self.stream = stream
|
||||
self.descriptions = descriptions
|
||||
|
||||
def getDescription(self, test):
|
||||
if self.descriptions:
|
||||
return test.shortDescription() or str(test)
|
||||
else:
|
||||
return str(test)
|
||||
|
||||
def addSuccess(self, test):
|
||||
_TestResult.addSuccess(self, test)
|
||||
filename = inspect.getfile(test.__class__)
|
||||
testname = test._testMethodName
|
||||
self.stream.writeln("TEST-PASS | %s | %s" % (filename, testname))
|
||||
|
||||
def addError(self, test, err):
|
||||
_TestResult.addError(self, test, err)
|
||||
self.printFail(test, err)
|
||||
|
||||
def addFailure(self, test, err):
|
||||
_TestResult.addFailure(self, test, err)
|
||||
self.printFail(test,err)
|
||||
|
||||
def printFail(self, test, err):
|
||||
exctype, value, tb = err
|
||||
# Skip test runner traceback levels
|
||||
while tb and self._is_relevant_tb_level(tb):
|
||||
tb = tb.tb_next
|
||||
if not tb:
|
||||
self.stream.writeln("TEST-UNEXPECTED-FAIL | NO TRACEBACK |")
|
||||
_f, _ln, _t = inspect.getframeinfo(tb)[:3]
|
||||
self.stream.writeln("TEST-UNEXPECTED-FAIL | %s | line %d, %s: %s" %
|
||||
(_f, _ln, _t, value.message))
|
||||
|
||||
def printErrorList(self):
|
||||
for test, err in self.errors:
|
||||
self.stream.writeln("ERROR: %s" % self.getDescription(test))
|
||||
self.stream.writeln("%s" % err)
|
||||
|
||||
|
||||
class MozTestRunner(_TestRunner):
|
||||
def _makeResult(self):
|
||||
return _MozTestResult(self.stream, self.descriptions)
|
||||
def run(self, test):
|
||||
result = self._makeResult()
|
||||
test(result)
|
||||
result.printErrorList()
|
||||
return result
|
|
@ -2068,21 +2068,14 @@ ifneq (,$(OBJS)$(XPIDLSRCS)$(SIMPLE_PROGRAMS))
|
|||
MDDEPEND_FILES := $(strip $(wildcard $(MDDEPDIR)/*.pp))
|
||||
|
||||
ifneq (,$(MDDEPEND_FILES))
|
||||
ifdef PERL
|
||||
# The script mddepend.pl checks the dependencies and writes to stdout
|
||||
# one rule to force out-of-date objects. For example,
|
||||
# foo.o boo.o: FORCE
|
||||
# The script has an advantage over including the *.pp files directly
|
||||
# because it handles the case when header files are removed from the build.
|
||||
# 'make' would complain that there is no way to build missing headers.
|
||||
ifeq (,$(MAKE_RESTARTS))
|
||||
$(MDDEPDIR)/.all.pp: FORCE
|
||||
@$(PERL) $(BUILD_TOOLS)/mddepend.pl $@ $(MDDEPEND_FILES)
|
||||
endif
|
||||
-include $(MDDEPDIR)/.all.pp
|
||||
else
|
||||
include $(MDDEPEND_FILES)
|
||||
endif
|
||||
ALL_PP_RESULTS = $(shell $(PERL) $(BUILD_TOOLS)/mddepend.pl - $(MDDEPEND_FILES))
|
||||
$(eval $(ALL_PP_RESULTS))
|
||||
endif
|
||||
|
||||
endif
|
||||
|
|
|
@ -0,0 +1,161 @@
|
|||
import unittest
|
||||
|
||||
import os, sys, os.path, time, inspect
|
||||
from filecmp import dircmp
|
||||
from tempfile import mkdtemp
|
||||
from shutil import rmtree, copy2
|
||||
from zipfile import ZipFile
|
||||
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
|
||||
|
||||
from mozunit import MozTestRunner
|
||||
from JarMaker import JarMaker
|
||||
|
||||
|
||||
class _TreeDiff(dircmp):
|
||||
"""Helper to report rich results on difference between two directories.
|
||||
"""
|
||||
def _fillDiff(self, dc, rv, basepath="%s"):
|
||||
rv['right_only'] += map(lambda l: basepath % l, dc.right_only)
|
||||
rv['left_only'] += map(lambda l: basepath % l, dc.left_only)
|
||||
rv['diff_files'] += map(lambda l: basepath % l, dc.diff_files)
|
||||
rv['funny'] += map(lambda l: basepath % l, dc.common_funny)
|
||||
rv['funny'] += map(lambda l: basepath % l, dc.funny_files)
|
||||
for subdir, _dc in dc.subdirs.iteritems():
|
||||
self._fillDiff(_dc, rv, basepath % (subdir + "/%s"))
|
||||
def allResults(self, left, right):
|
||||
rv = {'right_only':[], 'left_only':[],
|
||||
'diff_files':[], 'funny': []}
|
||||
self._fillDiff(self, rv)
|
||||
chunks = []
|
||||
if rv['right_only']:
|
||||
chunks.append('%s only in %s' % (', '.join(rv['right_only']),
|
||||
right))
|
||||
if rv['left_only']:
|
||||
chunks.append('%s only in %s' % (', '.join(rv['left_only']),
|
||||
left))
|
||||
if rv['diff_files']:
|
||||
chunks.append('%s differ' % ', '.join(rv['diff_files']))
|
||||
if rv['funny']:
|
||||
chunks.append("%s don't compare" % ', '.join(rv['funny']))
|
||||
return '; '.join(chunks)
|
||||
|
||||
class TestJarMaker(unittest.TestCase):
|
||||
"""
|
||||
Unit tests for JarMaker.py
|
||||
"""
|
||||
debug = False # set to True to debug failing tests on disk
|
||||
def setUp(self):
|
||||
self.tmpdir = mkdtemp()
|
||||
self.srcdir = os.path.join(self.tmpdir, 'src')
|
||||
os.mkdir(self.srcdir)
|
||||
self.builddir = os.path.join(self.tmpdir, 'build')
|
||||
os.mkdir(self.builddir)
|
||||
self.refdir = os.path.join(self.tmpdir, 'ref')
|
||||
os.mkdir(self.refdir)
|
||||
self.stagedir = os.path.join(self.tmpdir, 'stage')
|
||||
os.mkdir(self.stagedir)
|
||||
|
||||
def tearDown(self):
|
||||
if self.debug:
|
||||
print self.tmpdir
|
||||
else:
|
||||
rmtree(self.tmpdir)
|
||||
|
||||
def _jar_and_compare(self, *args, **kwargs):
|
||||
jm = JarMaker(outputFormat='jar')
|
||||
kwargs['jardir'] = os.path.join(self.builddir, 'chrome')
|
||||
if 'topsourcedir' not in kwargs:
|
||||
kwargs['topsourcedir'] = self.srcdir
|
||||
jm.makeJars(*args, **kwargs)
|
||||
cwd = os.getcwd()
|
||||
os.chdir(self.builddir)
|
||||
try:
|
||||
# expand build to stage
|
||||
for path, dirs, files in os.walk('.'):
|
||||
stagedir = os.path.join(self.stagedir, path)
|
||||
if not os.path.isdir(stagedir):
|
||||
os.mkdir(stagedir)
|
||||
for file in files:
|
||||
if file.endswith('.jar'):
|
||||
# expand jar
|
||||
stagepath = os.path.join(stagedir, file)
|
||||
os.mkdir(stagepath)
|
||||
zf = ZipFile(os.path.join(path, file))
|
||||
# extractall is only in 2.6, do this manually :-(
|
||||
for entry_name in zf.namelist():
|
||||
segs = entry_name.split('/')
|
||||
fname = segs.pop()
|
||||
dname = os.path.join(stagepath, *segs)
|
||||
if not os.path.isdir(dname):
|
||||
os.makedirs(dname)
|
||||
if not fname:
|
||||
# directory, we're done
|
||||
continue
|
||||
_c = zf.read(entry_name)
|
||||
open(os.path.join(dname, fname), 'wb').write(_c)
|
||||
zf.close()
|
||||
else:
|
||||
copy2(os.path.join(path, file), stagedir)
|
||||
# compare both dirs
|
||||
os.chdir('..')
|
||||
td = _TreeDiff('ref', 'stage')
|
||||
return td.allResults('reference', 'build')
|
||||
finally:
|
||||
os.chdir(cwd)
|
||||
|
||||
def test_a_simple_jar(self):
|
||||
'''Test a simple jar.mn'''
|
||||
# create src content
|
||||
jarf = open(os.path.join(self.srcdir, 'jar.mn'), 'w')
|
||||
jarf.write('''test.jar:
|
||||
dir/foo (bar)
|
||||
''')
|
||||
jarf.close()
|
||||
open(os.path.join(self.srcdir,'bar'),'w').write('content\n')
|
||||
# create reference
|
||||
refpath = os.path.join(self.refdir, 'chrome', 'test.jar', 'dir')
|
||||
os.makedirs(refpath)
|
||||
open(os.path.join(refpath, 'foo'), 'w').write('content\n')
|
||||
# call JarMaker
|
||||
rv = self._jar_and_compare((os.path.join(self.srcdir,'jar.mn'),),
|
||||
tuple(),
|
||||
sourcedirs = [self.srcdir])
|
||||
self.assertTrue(not rv, rv)
|
||||
|
||||
def test_k_multi_relative_jar(self):
|
||||
'''Test the API for multiple l10n jars, with different relative paths'''
|
||||
# create app src content
|
||||
def _mangle(relpath):
|
||||
'method we use to map relpath to srcpaths'
|
||||
return os.path.join(self.srcdir, 'other-' + relpath)
|
||||
jars = []
|
||||
for relpath in ('foo', 'bar'):
|
||||
ldir = os.path.join(self.srcdir, relpath, 'locales')
|
||||
os.makedirs(ldir)
|
||||
jp = os.path.join(ldir, 'jar.mn')
|
||||
jars.append(jp)
|
||||
open(jp, 'w').write('''ab-CD.jar:
|
||||
% locale app ab-CD %app
|
||||
app/''' + relpath + ' (%' + relpath + ''')
|
||||
''')
|
||||
ldir = _mangle(relpath)
|
||||
os.mkdir(ldir)
|
||||
open(os.path.join(ldir, relpath), 'w').write(relpath+" content\n")
|
||||
# create reference
|
||||
chrome_ref = os.path.join(self.refdir, 'chrome')
|
||||
os.mkdir(chrome_ref)
|
||||
mf = open(os.path.join(chrome_ref, 'ab-CD.manifest'), 'wb')
|
||||
mf.write('locale app ab-CD jar:ab-CD.jar!/app\n')
|
||||
mf.close()
|
||||
ldir = os.path.join(chrome_ref, 'ab-CD.jar', 'app')
|
||||
os.makedirs(ldir)
|
||||
for relpath in ('foo', 'bar'):
|
||||
open(os.path.join(ldir, relpath), 'w').write(relpath+" content\n")
|
||||
# call JarMaker
|
||||
difference = self._jar_and_compare(jars,
|
||||
(_mangle,),
|
||||
sourcedirs = [])
|
||||
self.assertTrue(not difference, difference)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(testRunner=MozTestRunner())
|
53
configure.in
53
configure.in
|
@ -288,18 +288,18 @@ case "$target" in
|
|||
|
||||
ac_exeext=.exe
|
||||
|
||||
_pwdw=`pwd -W`
|
||||
_pwd=`pwd`
|
||||
make OGLES_SDK_DIR="$OGLES_SDK_DIR" WINCE_SDK_DIR="$WINCE_SDK_DIR" TOPSRCDIR="$_topsrcdir" OBJDIR="$_pwdw" -C $srcdir/build/wince/tools
|
||||
_pwd=`pwd -W`
|
||||
_topsrcdirwin=`cd \`dirname $0\`; pwd -W`
|
||||
make OGLES_SDK_DIR="$OGLES_SDK_DIR" WINCE_SDK_DIR="$WINCE_SDK_DIR" TOPSRCDIR="$_topsrcdirwin" OBJDIR="$_pwd" -C $srcdir/build/wince/tools
|
||||
|
||||
CC="$_pwd/dist/sdk/bin/arm-wince-gcc"
|
||||
CXX="$_pwd/dist/sdk/bin/arm-wince-gcc"
|
||||
CPP="$_pwd/dist/sdk/bin/arm-wince-gcc -E -nologo"
|
||||
CXXCPP="$_pwd/dist/sdk/bin/arm-wince-gcc -TP -E -nologo"
|
||||
LD="$_pwd/dist/sdk/bin/arm-wince-link"
|
||||
AR="$_pwd/dist/sdk/bin/arm-wince-lib"
|
||||
AS="$_pwd/dist/sdk/bin/arm-wince-as"
|
||||
RC="$_pwd/dist/sdk/bin/arm-wince-res"
|
||||
CC="$_pwd/dist/sdk/bin/arm-wince-gcc.exe"
|
||||
CXX="$_pwd/dist/sdk/bin/arm-wince-gcc.exe"
|
||||
CPP="$_pwd/dist/sdk/bin/arm-wince-gcc.exe -E -nologo"
|
||||
CXXCPP="$_pwd/dist/sdk/bin/arm-wince-gcc.exe -TP -E -nologo"
|
||||
LD="$_pwd/dist/sdk/bin/arm-wince-link.exe"
|
||||
AR="$_pwd/dist/sdk/bin/arm-wince-lib.exe"
|
||||
AS="$_pwd/dist/sdk/bin/arm-wince-as.exe"
|
||||
RC="$_pwd/dist/sdk/bin/arm-wince-res.exe"
|
||||
|
||||
|
||||
echo -----------------------------------------------------------------------------
|
||||
|
@ -2010,7 +2010,8 @@ case "$target" in
|
|||
TARGET_COMPILER_ABI=msvc
|
||||
_PLATFORM_DEFAULT_TOOLKIT=cairo-windows
|
||||
_PLATFORM_MOZ_DISABLE_VISTA_SDK_REQUIREMENTS=1
|
||||
MOZ_TOOLS_DIR=`echo $MOZ_TOOLS`
|
||||
MOZ_TOOLS_DIR=`cd $MOZ_TOOLS && pwd -W`
|
||||
MOZ_BUILD_ROOT=`cd $MOZ_BUILD_ROOT && pwd -W`
|
||||
AR_LIST="$AR -list"
|
||||
AR_EXTRACT="$AR -extract"
|
||||
AR_DELETE="$AR d"
|
||||
|
@ -4159,7 +4160,15 @@ if test "$ac_cv_trouble_comparing_to_zero" = yes ; then
|
|||
AC_DEFINE(HAVE_CPP_TROUBLE_COMPARING_TO_ZERO)
|
||||
fi
|
||||
|
||||
|
||||
AC_CACHE_CHECK(for __thread keyword for TLS variables,
|
||||
ac_cv_thread_keyword,
|
||||
[AC_TRY_COMPILE([__thread bool tlsIsMainThread = false;],
|
||||
[return tlsIsMainThread;],
|
||||
ac_cv_thread_keyword=yes,
|
||||
ac_cv_thread_keyword=no)])
|
||||
if test "$ac_cv_thread_keyword" = yes; then
|
||||
AC_DEFINE(HAVE_THREAD_TLS_KEYWORD)
|
||||
fi
|
||||
|
||||
dnl End of C++ language/feature checks
|
||||
AC_LANG_C
|
||||
|
@ -4749,12 +4758,16 @@ photon)
|
|||
|
||||
cairo-windows)
|
||||
MOZ_WIDGET_TOOLKIT=windows
|
||||
if test -z "$WINCE"; then
|
||||
MOZ_WEBGL=1
|
||||
fi
|
||||
;;
|
||||
|
||||
cairo-gtk2|cairo-gtk2-x11)
|
||||
MOZ_WIDGET_TOOLKIT=gtk2
|
||||
MOZ_ENABLE_GTK2=1
|
||||
MOZ_ENABLE_XREMOTE=1
|
||||
MOZ_WEBGL=1
|
||||
|
||||
AC_DEFINE(MOZ_X11)
|
||||
MOZ_X11=1
|
||||
|
@ -4767,6 +4780,7 @@ cairo-gtk2|cairo-gtk2-x11)
|
|||
cairo-gtk2-dfb)
|
||||
MOZ_WIDGET_TOOLKIT=gtk2
|
||||
MOZ_ENABLE_GTK2=1
|
||||
MOZ_WEBGL=1
|
||||
|
||||
AC_DEFINE(MOZ_DFB)
|
||||
MOZ_DFB=1
|
||||
|
@ -4819,6 +4833,7 @@ cairo-cocoa)
|
|||
CXXFLAGS="$CXXFLAGS $TK_CFLAGS"
|
||||
LIBXUL_LIBS='$(XPCOM_FROZEN_LDOPTS) $(LIBXUL_DIST)/bin/XUL -lobjc'
|
||||
MOZ_FS_LAYOUT=bundle
|
||||
MOZ_WEBGL=1
|
||||
;;
|
||||
esac
|
||||
|
||||
|
@ -6196,6 +6211,7 @@ if test $NS_OSSO; then
|
|||
fi
|
||||
AC_DEFINE(NS_OSSO)
|
||||
MOZ_GFX_OPTIMIZE_MOBILE=1
|
||||
MOZ_WEBGL=
|
||||
fi
|
||||
AC_SUBST(LIBOSSO_CFLAGS)
|
||||
AC_SUBST(LIBOSSO_LIBS)
|
||||
|
@ -7806,6 +7822,7 @@ AC_SUBST(MOZ_PLACES_BOOKMARKS)
|
|||
AC_SUBST(MOZ_STORAGE)
|
||||
AC_SUBST(MOZ_FEEDS)
|
||||
AC_SUBST(NS_PRINTING)
|
||||
AC_SUBST(MOZ_WEBGL)
|
||||
|
||||
AC_SUBST(MOZ_JAVAXPCOM)
|
||||
AC_SUBST(JAVA_INCLUDE_PATH)
|
||||
|
@ -8036,6 +8053,16 @@ if test "$MOZ_X11"; then
|
|||
fi
|
||||
|
||||
fi # MOZ_X11
|
||||
|
||||
dnl Check for headers, etc. needed by WebGL.
|
||||
if test -n "$MOZ_WEBGL"; then
|
||||
if test "$MOZ_WIDGET_TOOLKIT" = gtk2; then
|
||||
AC_CHECK_HEADER(GL/glx.h)
|
||||
if test "$ac_cv_header_GL_glx_h" != "yes"; then
|
||||
AC_MSG_ERROR([Can't find header GL/glx.h for WebGL (install mesa-common-dev (Ubuntu), mesa-libGL-devel (Fedora), or Mesa (SuSE))])
|
||||
fi
|
||||
fi
|
||||
fi # MOZ_WEBGL
|
||||
fi # COMPILE_ENVIRONMENT
|
||||
|
||||
dnl Set various defines and substitutions
|
||||
|
|
|
@ -129,6 +129,8 @@ public:
|
|||
mCompatMode(eCompatibility_FullStandards),
|
||||
mIsInitialDocumentInWindow(PR_FALSE),
|
||||
mMayStartLayout(PR_TRUE),
|
||||
mVisible(PR_TRUE),
|
||||
mRemovedFromDocShell(PR_FALSE),
|
||||
// mAllowDNSPrefetch starts true, so that we can always reliably && it
|
||||
// with various values that might disable it. Since we never prefetch
|
||||
// unless we get a window, and in that case the docshell value will get
|
||||
|
@ -689,12 +691,10 @@ public:
|
|||
nsIPrincipal* aPrincipal) = 0;
|
||||
|
||||
/**
|
||||
* Set the container (docshell) for this document.
|
||||
* Set the container (docshell) for this document. Virtual so that
|
||||
* docshell can call it.
|
||||
*/
|
||||
void SetContainer(nsISupports *aContainer)
|
||||
{
|
||||
mDocumentContainer = do_GetWeakReference(aContainer);
|
||||
}
|
||||
virtual void SetContainer(nsISupports *aContainer);
|
||||
|
||||
/**
|
||||
* Get the container (docshell) for this document.
|
||||
|
@ -1120,6 +1120,16 @@ public:
|
|||
* called yet.
|
||||
*/
|
||||
PRBool IsShowing() { return mIsShowing; }
|
||||
/**
|
||||
* Return whether the document is currently visible (in the sense of
|
||||
* OnPageHide having been called and OnPageShow not yet having been called)
|
||||
*/
|
||||
PRBool IsVisible() { return mVisible; }
|
||||
/**
|
||||
* Return true when this document is active, i.e., the active document
|
||||
* in a content viewer.
|
||||
*/
|
||||
PRBool IsActive() { return mDocumentContainer && !mRemovedFromDocShell; }
|
||||
|
||||
void RegisterFreezableElement(nsIContent* aContent);
|
||||
PRBool UnregisterFreezableElement(nsIContent* aContent);
|
||||
|
@ -1281,6 +1291,15 @@ protected:
|
|||
// True iff IsShowing() should be returning true
|
||||
PRPackedBool mIsShowing;
|
||||
|
||||
// True iff the document "page" is not hidden (i.e. currently in the
|
||||
// bfcache)
|
||||
PRPackedBool mVisible;
|
||||
|
||||
// True if our content viewer has been removed from the docshell
|
||||
// (it may still be displayed, but in zombie state). Form control data
|
||||
// has been saved.
|
||||
PRPackedBool mRemovedFromDocShell;
|
||||
|
||||
// True iff DNS prefetch is allowed for this document. Note that if the
|
||||
// document has no window, DNS prefetch won't be performed no matter what.
|
||||
PRPackedBool mAllowDNSPrefetch;
|
||||
|
|
|
@ -228,7 +228,10 @@ interface nsIXMLHttpRequest : nsISupports
|
|||
* @param password (optional) A password for authentication if necessary.
|
||||
* The default value is the empty string
|
||||
*/
|
||||
void open(in AUTF8String method, in AUTF8String url);
|
||||
[optional_argc] void open(in AUTF8String method, in AUTF8String url,
|
||||
[optional] in boolean async,
|
||||
[optional] in DOMString user,
|
||||
[optional] in DOMString password);
|
||||
|
||||
/**
|
||||
* Sends the request. If the request is asynchronous, returns
|
||||
|
|
|
@ -328,7 +328,25 @@ nsContentAreaDragDrop::DragOver(nsIDOMDragEvent* inEvent)
|
|||
}
|
||||
}
|
||||
|
||||
session->SetCanDrop(dropAllowed);
|
||||
nsCOMPtr<nsIDOMNSEvent> e = do_QueryInterface(inEvent);
|
||||
NS_ENSURE_STATE(e);
|
||||
nsCOMPtr<nsIDOMEventTarget> target;
|
||||
e->GetOriginalTarget(getter_AddRefs(target));
|
||||
nsCOMPtr<nsINode> node = do_QueryInterface(target);
|
||||
if (!node) {
|
||||
nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(target);
|
||||
if (win) {
|
||||
node = do_QueryInterface(win->GetExtantDocument());
|
||||
}
|
||||
}
|
||||
PRBool isChrome =
|
||||
node ? nsContentUtils::IsChromeDoc(node->GetOwnerDoc()) : PR_FALSE;
|
||||
if (isChrome) {
|
||||
session->SetCanDrop(dropAllowed);
|
||||
} else if (dropAllowed) {
|
||||
inEvent->PreventDefault();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -5069,13 +5069,10 @@ nsContentUtils::CanAccessNativeAnon()
|
|||
fp = nsnull;
|
||||
}
|
||||
|
||||
void *annotation = fp ? JS_GetFrameAnnotation(cx, fp) : nsnull;
|
||||
PRBool privileged;
|
||||
if (NS_SUCCEEDED(principal->IsCapabilityEnabled("UniversalXPConnect",
|
||||
annotation,
|
||||
&privileged)) &&
|
||||
if (NS_SUCCEEDED(sSecurityManager->IsSystemPrincipal(principal, &privileged)) &&
|
||||
privileged) {
|
||||
// UniversalXPConnect things are allowed to touch us.
|
||||
// Chrome things are allowed to touch us.
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
|
@ -5089,6 +5086,12 @@ nsContentUtils::CanAccessNativeAnon()
|
|||
return PR_TRUE;
|
||||
}
|
||||
|
||||
// Before we throw, check for UniversalXPConnect.
|
||||
nsresult rv = sSecurityManager->IsCapabilityEnabled("UniversalXPConnect", &privileged);
|
||||
if (NS_SUCCEEDED(rv) && privileged) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
|
|
|
@ -169,6 +169,7 @@ static NS_DEFINE_CID(kDOMEventGroupCID, NS_DOMEVENTGROUP_CID);
|
|||
#include "nsIPropertyBag2.h"
|
||||
#include "nsIDOMPageTransitionEvent.h"
|
||||
#include "nsFrameLoader.h"
|
||||
#include "nsHTMLMediaElement.h"
|
||||
|
||||
#include "mozAutoDocUpdate.h"
|
||||
|
||||
|
@ -1481,8 +1482,7 @@ nsDOMImplementation::Init(nsIURI* aDocumentURI, nsIURI* aBaseURI,
|
|||
// bother initializing members to 0.
|
||||
|
||||
nsDocument::nsDocument(const char* aContentType)
|
||||
: nsIDocument(),
|
||||
mVisible(PR_TRUE)
|
||||
: nsIDocument()
|
||||
{
|
||||
mContentType = aContentType;
|
||||
|
||||
|
@ -3575,6 +3575,25 @@ nsDocument::GetScopeObject()
|
|||
return scope;
|
||||
}
|
||||
|
||||
static void
|
||||
NotifyActivityChanged(nsIContent *aContent, void *aUnused)
|
||||
{
|
||||
#ifdef MOZ_MEDIA
|
||||
nsCOMPtr<nsIDOMHTMLMediaElement> domMediaElem(do_QueryInterface(aContent));
|
||||
if (domMediaElem) {
|
||||
nsHTMLMediaElement* mediaElem = static_cast<nsHTMLMediaElement*>(aContent);
|
||||
mediaElem->NotifyOwnerDocumentActivityChanged();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
nsIDocument::SetContainer(nsISupports* aContainer)
|
||||
{
|
||||
mDocumentContainer = do_GetWeakReference(aContainer);
|
||||
EnumerateFreezableElements(NotifyActivityChanged, nsnull);
|
||||
}
|
||||
|
||||
void
|
||||
nsDocument::SetScriptGlobalObject(nsIScriptGlobalObject *aScriptGlobalObject)
|
||||
{
|
||||
|
@ -6973,6 +6992,7 @@ nsDocument::RemovedFromDocShell()
|
|||
return;
|
||||
|
||||
mRemovedFromDocShell = PR_TRUE;
|
||||
EnumerateFreezableElements(NotifyActivityChanged, nsnull);
|
||||
|
||||
PRUint32 i, count = mChildren.ChildCount();
|
||||
for (i = 0; i < count; ++i) {
|
||||
|
@ -7157,6 +7177,8 @@ void
|
|||
nsDocument::OnPageShow(PRBool aPersisted, nsIDOMEventTarget* aDispatchStartTarget)
|
||||
{
|
||||
mVisible = PR_TRUE;
|
||||
|
||||
EnumerateFreezableElements(NotifyActivityChanged, nsnull);
|
||||
UpdateLinkMap();
|
||||
|
||||
nsIContent* root = GetRootContent();
|
||||
|
@ -7237,6 +7259,7 @@ nsDocument::OnPageHide(PRBool aPersisted, nsIDOMEventTarget* aDispatchStartTarge
|
|||
DispatchPageTransition(target, NS_LITERAL_STRING("pagehide"), aPersisted);
|
||||
|
||||
mVisible = PR_FALSE;
|
||||
EnumerateFreezableElements(NotifyActivityChanged, nsnull);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -1171,14 +1171,8 @@ protected:
|
|||
|
||||
// True if the document has been detached from its content viewer.
|
||||
PRPackedBool mIsGoingAway:1;
|
||||
// True if our content viewer has been removed from the docshell
|
||||
// (it may still be displayed, but in zombie state). Form control data
|
||||
// has been saved.
|
||||
PRPackedBool mRemovedFromDocShell:1;
|
||||
// True if the document is being destroyed.
|
||||
PRPackedBool mInDestructor:1;
|
||||
// True if the document "page" is not hidden
|
||||
PRPackedBool mVisible:1;
|
||||
// True if document has ever had script handling object.
|
||||
PRPackedBool mHasHadScriptHandlingObject:1;
|
||||
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#include "nsPresContext.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIContentViewer.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
|
@ -64,6 +65,7 @@
|
|||
#include "nsUnicharUtils.h"
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsIScrollable.h"
|
||||
#include "nsFrameLoader.h"
|
||||
#include "nsIDOMEventTarget.h"
|
||||
#include "nsIFrame.h"
|
||||
|
@ -74,6 +76,8 @@
|
|||
#include "nsEventDispatcher.h"
|
||||
#include "nsISHistory.h"
|
||||
#include "nsISHistoryInternal.h"
|
||||
#include "nsIDOMNSHTMLDocument.h"
|
||||
#include "nsIView.h"
|
||||
|
||||
#include "nsIURI.h"
|
||||
#include "nsIURL.h"
|
||||
|
@ -465,6 +469,107 @@ AllDescendantsOfType(nsIDocShellTreeItem* aParentItem, PRInt32 aType)
|
|||
return PR_TRUE;
|
||||
}
|
||||
|
||||
bool
|
||||
nsFrameLoader::Show(PRInt32 marginWidth, PRInt32 marginHeight,
|
||||
PRInt32 scrollbarPrefX, PRInt32 scrollbarPrefY,
|
||||
nsIFrameFrame* frame)
|
||||
{
|
||||
nsContentType contentType;
|
||||
|
||||
nsresult rv = EnsureDocShell();
|
||||
if (NS_FAILED(rv)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mDocShell)
|
||||
return false;
|
||||
|
||||
nsCOMPtr<nsIPresShell> presShell;
|
||||
mDocShell->GetPresShell(getter_AddRefs(presShell));
|
||||
if (presShell)
|
||||
return true;
|
||||
|
||||
mDocShell->SetMarginWidth(marginWidth);
|
||||
mDocShell->SetMarginHeight(marginHeight);
|
||||
|
||||
nsCOMPtr<nsIScrollable> sc = do_QueryInterface(mDocShell);
|
||||
if (sc) {
|
||||
sc->SetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_X,
|
||||
scrollbarPrefX);
|
||||
sc->SetDefaultScrollbarPreferences(nsIScrollable::ScrollOrientation_Y,
|
||||
scrollbarPrefY);
|
||||
}
|
||||
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeItem> treeItem = do_QueryInterface(mDocShell);
|
||||
NS_ASSERTION(treeItem,
|
||||
"Found a nsIDocShell that isn't a nsIDocShellTreeItem.");
|
||||
|
||||
PRInt32 itemType;
|
||||
treeItem->GetItemType(&itemType);
|
||||
|
||||
if (itemType == nsIDocShellTreeItem::typeChrome)
|
||||
contentType = eContentTypeUI;
|
||||
else {
|
||||
nsCOMPtr<nsIDocShellTreeItem> sameTypeParent;
|
||||
treeItem->GetSameTypeParent(getter_AddRefs(sameTypeParent));
|
||||
contentType = sameTypeParent ? eContentTypeContentFrame : eContentTypeContent;
|
||||
}
|
||||
|
||||
nsIView* view = frame->CreateViewAndWidget(contentType);
|
||||
if (!view)
|
||||
return false;
|
||||
|
||||
nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(mDocShell);
|
||||
NS_ASSERTION(baseWindow, "Found a nsIDocShell that isn't a nsIBaseWindow.");
|
||||
baseWindow->InitWindow(nsnull, view->GetWidget(), 0, 0, 10, 10);
|
||||
// This is kinda whacky, this "Create()" call doesn't really
|
||||
// create anything, one starts to wonder why this was named
|
||||
// "Create"...
|
||||
baseWindow->Create();
|
||||
baseWindow->SetVisibility(PR_TRUE);
|
||||
|
||||
// Trigger editor re-initialization if midas is turned on in the
|
||||
// sub-document. This shouldn't be necessary, but given the way our
|
||||
// editor works, it is. See
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=284245
|
||||
mDocShell->GetPresShell(getter_AddRefs(presShell));
|
||||
if (presShell) {
|
||||
nsCOMPtr<nsIDOMNSHTMLDocument> doc =
|
||||
do_QueryInterface(presShell->GetDocument());
|
||||
|
||||
if (doc) {
|
||||
nsAutoString designMode;
|
||||
doc->GetDesignMode(designMode);
|
||||
|
||||
if (designMode.EqualsLiteral("on")) {
|
||||
doc->SetDesignMode(NS_LITERAL_STRING("off"));
|
||||
doc->SetDesignMode(NS_LITERAL_STRING("on"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
nsFrameLoader::Hide()
|
||||
{
|
||||
if (!mDocShell)
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIContentViewer> contentViewer;
|
||||
mDocShell->GetContentViewer(getter_AddRefs(contentViewer));
|
||||
if (contentViewer)
|
||||
contentViewer->SetSticky(PR_FALSE);
|
||||
|
||||
nsCOMPtr<nsIBaseWindow> baseWin = do_QueryInterface(mDocShell);
|
||||
NS_ASSERTION(baseWin,
|
||||
"Found an nsIDocShell which doesn't implement nsIBaseWindow.");
|
||||
baseWin->SetVisibility(PR_FALSE);
|
||||
baseWin->SetParentWidget(nsnull);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsFrameLoader::SwapWithOtherLoader(nsFrameLoader* aOther,
|
||||
nsRefPtr<nsFrameLoader>& aFirstToSwap,
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
|
||||
class nsIContent;
|
||||
class nsIURI;
|
||||
class nsIFrameFrame;
|
||||
|
||||
class nsFrameLoader : public nsIFrameLoader
|
||||
{
|
||||
|
@ -80,6 +81,21 @@ public:
|
|||
void Finalize();
|
||||
nsIDocShell* GetExistingDocShell() { return mDocShell; }
|
||||
|
||||
/**
|
||||
* Called from the layout frame associated with this frame loader;
|
||||
* this notifies us to hook up with the widget and view.
|
||||
*/
|
||||
bool Show(PRInt32 marginWidth, PRInt32 marginHeight,
|
||||
PRInt32 scrollbarPrefX, PRInt32 scrollbarPrefY,
|
||||
nsIFrameFrame* frame);
|
||||
|
||||
/**
|
||||
* Called from the layout frame associated with this frame loader, when
|
||||
* the frame is being torn down; this notifies us that out widget and view
|
||||
* are going away and we should unhook from them.
|
||||
*/
|
||||
void Hide();
|
||||
|
||||
// The guts of an nsIFrameLoaderOwner::SwapFrameLoader implementation. A
|
||||
// frame loader owner needs to call this, and pass in the two references to
|
||||
// nsRefPtrs for frame loaders that need to be swapped.
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
#endif
|
||||
#include "nsBindingManager.h"
|
||||
#include "nsGenericHTMLElement.h"
|
||||
#include "nsHTMLMediaElement.h"
|
||||
|
||||
// This macro expects the ownerDocument of content_ to be in scope as
|
||||
// |nsIDocument* doc|
|
||||
|
@ -604,6 +605,8 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, PRBool aClone, PRBool aDeep,
|
|||
|
||||
nsIDocument* newDoc = aNode->GetOwnerDoc();
|
||||
if (newDoc) {
|
||||
// XXX what if oldDoc is null, we don't know if this should be
|
||||
// registered or not! Can that really happen?
|
||||
if (wasRegistered) {
|
||||
newDoc->RegisterFreezableElement(static_cast<nsIContent*>(aNode));
|
||||
}
|
||||
|
@ -620,6 +623,16 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, PRBool aClone, PRBool aDeep,
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef MOZ_MEDIA
|
||||
if (wasRegistered && oldDoc != newDoc) {
|
||||
nsCOMPtr<nsIDOMHTMLMediaElement> domMediaElem(do_QueryInterface(aNode));
|
||||
if (domMediaElem) {
|
||||
nsHTMLMediaElement* mediaElem = static_cast<nsHTMLMediaElement*>(aNode);
|
||||
mediaElem->NotifyOwnerDocumentActivityChanged();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (elem) {
|
||||
elem->RecompileScriptEventListeners();
|
||||
}
|
||||
|
|
|
@ -1753,30 +1753,14 @@ nsXMLHttpRequest::OpenRequest(const nsACString& method,
|
|||
|
||||
/* void open (in AUTF8String method, in AUTF8String url); */
|
||||
NS_IMETHODIMP
|
||||
nsXMLHttpRequest::Open(const nsACString& method, const nsACString& url)
|
||||
nsXMLHttpRequest::Open(const nsACString& method, const nsACString& url,
|
||||
PRBool async, const nsAString& user,
|
||||
const nsAString& password, PRUint8 optional_argc)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
PRBool async = PR_TRUE;
|
||||
nsAutoString user, password;
|
||||
|
||||
nsAXPCNativeCallContext *cc = nsnull;
|
||||
nsIXPConnect *xpc = nsContentUtils::XPConnect();
|
||||
if (xpc) {
|
||||
rv = xpc->GetCurrentNativeCallContext(&cc);
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(rv) && cc) {
|
||||
PRUint32 argc;
|
||||
rv = cc->GetArgc(&argc);
|
||||
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
|
||||
jsval* argv;
|
||||
rv = cc->GetArgvPtr(&argv);
|
||||
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
|
||||
JSContext* cx;
|
||||
rv = cc->GetJSContext(&cx);
|
||||
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
if (nsContentUtils::GetCurrentJSContext()) {
|
||||
// We're (likely) called from JS
|
||||
|
||||
// Find out if UniversalBrowserRead privileges are enabled
|
||||
if (nsContentUtils::IsCallerTrustedForRead()) {
|
||||
|
@ -1784,33 +1768,11 @@ nsXMLHttpRequest::Open(const nsACString& method, const nsACString& url)
|
|||
} else {
|
||||
mState &= ~XML_HTTP_REQUEST_XSITEENABLED;
|
||||
}
|
||||
}
|
||||
|
||||
if (argc > 2) {
|
||||
JSAutoRequest ar(cx);
|
||||
JSBool asyncBool;
|
||||
::JS_ValueToBoolean(cx, argv[2], &asyncBool);
|
||||
async = (PRBool)asyncBool;
|
||||
|
||||
if (argc > 3 && !JSVAL_IS_NULL(argv[3]) && !JSVAL_IS_VOID(argv[3])) {
|
||||
JSString* userStr = ::JS_ValueToString(cx, argv[3]);
|
||||
|
||||
if (userStr) {
|
||||
user.Assign(reinterpret_cast<PRUnichar *>
|
||||
(::JS_GetStringChars(userStr)),
|
||||
::JS_GetStringLength(userStr));
|
||||
}
|
||||
|
||||
if (argc > 4 && !JSVAL_IS_NULL(argv[4]) && !JSVAL_IS_VOID(argv[4])) {
|
||||
JSString* passwdStr = JS_ValueToString(cx, argv[4]);
|
||||
|
||||
if (passwdStr) {
|
||||
password.Assign(reinterpret_cast<PRUnichar *>
|
||||
(::JS_GetStringChars(passwdStr)),
|
||||
::JS_GetStringLength(passwdStr));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!optional_argc) {
|
||||
// No optional arguments were passed in. Default async to true.
|
||||
async = PR_TRUE;
|
||||
}
|
||||
|
||||
return OpenRequest(method, url, async, user, password);
|
||||
|
|
|
@ -55,12 +55,7 @@ CPPSRCS = \
|
|||
|
||||
# Canvas 3D Pieces
|
||||
|
||||
# only allow on platforms/toolkits we know are good
|
||||
ifneq (,$(NS_OSSO)$(WINCE)$(filter-out windows cocoa gtk2,$(MOZ_WIDGET_TOOLKIT)))
|
||||
DISABLE_WEBGL=1
|
||||
endif
|
||||
|
||||
ifndef DISABLE_WEBGL
|
||||
ifdef MOZ_WEBGL
|
||||
|
||||
CPPSRCS += \
|
||||
WebGLContext.cpp \
|
||||
|
|
|
@ -621,14 +621,6 @@ protected:
|
|||
return mStyleStack[mSaveCount];
|
||||
}
|
||||
|
||||
// stolen from nsJSUtils
|
||||
static PRBool ConvertJSValToUint32(PRUint32* aProp, JSContext* aContext,
|
||||
jsval aValue);
|
||||
static PRBool ConvertJSValToXPCObject(nsISupports** aSupports, REFNSIID aIID,
|
||||
JSContext* aContext, jsval aValue);
|
||||
static PRBool ConvertJSValToDouble(double* aProp, JSContext* aContext,
|
||||
jsval aValue);
|
||||
|
||||
// other helpers
|
||||
void GetAppUnitsValues(PRUint32 *perDevPixel, PRUint32 *perCSSPixel) {
|
||||
// If we don't have a canvas element, we just return something generic.
|
||||
|
@ -2928,45 +2920,19 @@ bitblt(gfxImageSurface *s, int src_x, int src_y, int width, int height,
|
|||
// -- render the region defined by (sx,sy,sw,wh) in image-local space into the region (dx,dy,dw,dh) on the canvas
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCanvasRenderingContext2D::DrawImage()
|
||||
nsCanvasRenderingContext2D::DrawImage(nsIDOMElement *imgElt, float a1,
|
||||
float a2, float a3, float a4, float a5,
|
||||
float a6, float a7, float a8,
|
||||
PRUint8 optional_argc)
|
||||
{
|
||||
NS_ENSURE_ARG(imgElt);
|
||||
|
||||
nsresult rv;
|
||||
gfxRect dirty;
|
||||
|
||||
nsAXPCNativeCallContext *ncc = nsnull;
|
||||
rv = nsContentUtils::XPConnect()->
|
||||
GetCurrentNativeCallContext(&ncc);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!ncc)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
JSContext *ctx = nsnull;
|
||||
|
||||
rv = ncc->GetJSContext(&ctx);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRUint32 argc;
|
||||
jsval *argv = nsnull;
|
||||
|
||||
ncc->GetArgc(&argc);
|
||||
ncc->GetArgvPtr(&argv);
|
||||
|
||||
// we always need at least an image and a dx,dy
|
||||
if (argc < 3)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
JSAutoRequest ar(ctx);
|
||||
|
||||
double sx,sy,sw,sh;
|
||||
double dx,dy,dw,dh;
|
||||
|
||||
nsCOMPtr<nsIDOMElement> imgElt;
|
||||
if (!ConvertJSValToXPCObject(getter_AddRefs(imgElt),
|
||||
NS_GET_IID(nsIDOMElement),
|
||||
ctx, argv[0]))
|
||||
return NS_ERROR_DOM_TYPE_MISMATCH_ERR;
|
||||
|
||||
gfxMatrix matrix;
|
||||
nsRefPtr<gfxPattern> pattern;
|
||||
nsRefPtr<gfxPath> path;
|
||||
|
@ -3000,40 +2966,36 @@ nsCanvasRenderingContext2D::DrawImage()
|
|||
|
||||
gfxContextPathAutoSaveRestore pathSR(mThebes, PR_FALSE);
|
||||
|
||||
#define GET_ARG(dest,whicharg) \
|
||||
do { if (!ConvertJSValToDouble(dest, ctx, whicharg)) { rv = NS_ERROR_INVALID_ARG; goto FINISH; } } while (0)
|
||||
|
||||
rv = NS_OK;
|
||||
|
||||
if (argc == 3) {
|
||||
GET_ARG(&dx, argv[1]);
|
||||
GET_ARG(&dy, argv[2]);
|
||||
if (optional_argc == 0) {
|
||||
dx = a1;
|
||||
dy = a2;
|
||||
sx = sy = 0.0;
|
||||
dw = sw = (double) imgSize.width;
|
||||
dh = sh = (double) imgSize.height;
|
||||
} else if (argc == 5) {
|
||||
GET_ARG(&dx, argv[1]);
|
||||
GET_ARG(&dy, argv[2]);
|
||||
GET_ARG(&dw, argv[3]);
|
||||
GET_ARG(&dh, argv[4]);
|
||||
} else if (optional_argc == 2) {
|
||||
dx = a1;
|
||||
dy = a2;
|
||||
dw = a3;
|
||||
dh = a4;
|
||||
sx = sy = 0.0;
|
||||
sw = (double) imgSize.width;
|
||||
sh = (double) imgSize.height;
|
||||
} else if (argc == 9) {
|
||||
GET_ARG(&sx, argv[1]);
|
||||
GET_ARG(&sy, argv[2]);
|
||||
GET_ARG(&sw, argv[3]);
|
||||
GET_ARG(&sh, argv[4]);
|
||||
GET_ARG(&dx, argv[5]);
|
||||
GET_ARG(&dy, argv[6]);
|
||||
GET_ARG(&dw, argv[7]);
|
||||
GET_ARG(&dh, argv[8]);
|
||||
} else if (optional_argc == 6) {
|
||||
sx = a1;
|
||||
sy = a2;
|
||||
sw = a3;
|
||||
sh = a4;
|
||||
dx = a5;
|
||||
dy = a6;
|
||||
dw = a7;
|
||||
dh = a8;
|
||||
} else {
|
||||
// XXX ERRMSG we need to report an error to developers here! (bug 329026)
|
||||
rv = NS_ERROR_INVALID_ARG;
|
||||
goto FINISH;
|
||||
}
|
||||
#undef GET_ARG
|
||||
|
||||
if (dw == 0.0 || dh == 0.0) {
|
||||
rv = NS_OK;
|
||||
|
@ -3042,7 +3004,7 @@ nsCanvasRenderingContext2D::DrawImage()
|
|||
goto FINISH;
|
||||
}
|
||||
|
||||
if (!FloatValidate(sx,sy,sw,sh) || !FloatValidate(dx,dy,dw,dh)) {
|
||||
if (!FloatValidate(sx, sy, sw, sh) || !FloatValidate(dx, dy, dw, dh)) {
|
||||
rv = NS_ERROR_DOM_SYNTAX_ERR;
|
||||
goto FINISH;
|
||||
}
|
||||
|
@ -3228,61 +3190,6 @@ nsCanvasRenderingContext2D::GetGlobalCompositeOperation(nsAString& op)
|
|||
}
|
||||
|
||||
|
||||
//
|
||||
// Utils
|
||||
//
|
||||
PRBool
|
||||
nsCanvasRenderingContext2D::ConvertJSValToUint32(PRUint32* aProp, JSContext* aContext,
|
||||
jsval aValue)
|
||||
{
|
||||
uint32 temp;
|
||||
if (::JS_ValueToECMAUint32(aContext, aValue, &temp)) {
|
||||
*aProp = (PRUint32)temp;
|
||||
}
|
||||
else {
|
||||
::JS_ReportError(aContext, "Parameter must be an integer");
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsCanvasRenderingContext2D::ConvertJSValToDouble(double* aProp, JSContext* aContext,
|
||||
jsval aValue)
|
||||
{
|
||||
jsdouble temp;
|
||||
if (::JS_ValueToNumber(aContext, aValue, &temp)) {
|
||||
*aProp = (jsdouble)temp;
|
||||
}
|
||||
else {
|
||||
::JS_ReportError(aContext, "Parameter must be a number");
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsCanvasRenderingContext2D::ConvertJSValToXPCObject(nsISupports** aSupports, REFNSIID aIID,
|
||||
JSContext* aContext, jsval aValue)
|
||||
{
|
||||
*aSupports = nsnull;
|
||||
if (JSVAL_IS_NULL(aValue)) {
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
if (JSVAL_IS_OBJECT(aValue)) {
|
||||
// WrapJS does all the work to recycle an existing wrapper and/or do a QI
|
||||
nsresult rv = nsContentUtils::XPConnect()->
|
||||
WrapJS(aContext, JSVAL_TO_OBJECT(aValue), aIID, (void**)aSupports);
|
||||
|
||||
return NS_SUCCEEDED(rv);
|
||||
}
|
||||
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
FlushLayoutForTree(nsIDOMWindow* aWindow)
|
||||
{
|
||||
|
@ -3401,6 +3308,15 @@ nsCanvasRenderingContext2D::DrawWindow(nsIDOMWindow* aWindow, float aX, float aY
|
|||
//
|
||||
// device pixel getting/setting
|
||||
//
|
||||
extern "C" {
|
||||
#include "jstypes.h"
|
||||
JS_FRIEND_API(JSBool)
|
||||
js_CoerceArrayToCanvasImageData(JSObject *obj, jsuint offset, jsuint count,
|
||||
JSUint8 *dest);
|
||||
JS_FRIEND_API(JSObject *)
|
||||
js_NewArrayObjectWithCapacity(JSContext *cx, jsuint capacity, jsval **vector);
|
||||
}
|
||||
|
||||
|
||||
// ImageData getImageData (in float x, in float y, in float width, in float height);
|
||||
NS_IMETHODIMP
|
||||
|
@ -3472,10 +3388,14 @@ nsCanvasRenderingContext2D::GetImageData()
|
|||
if (len > (((PRUint32)0xfff00000)/sizeof(jsval)))
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
nsAutoArrayPtr<jsval> jsvector(new (std::nothrow) jsval[w * h * 4]);
|
||||
if (!jsvector)
|
||||
jsval *dest;
|
||||
JSObject *dataArray = js_NewArrayObjectWithCapacity(ctx, len, &dest);
|
||||
if (!dataArray)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
jsval *dest = jsvector.get();
|
||||
|
||||
nsAutoGCRoot arrayGCRoot(&dataArray, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRUint8 *row;
|
||||
for (int j = 0; j < h; j++) {
|
||||
row = surfaceData + surfaceDataOffset + (surfaceDataStride * j);
|
||||
|
@ -3507,13 +3427,8 @@ nsCanvasRenderingContext2D::GetImageData()
|
|||
}
|
||||
}
|
||||
|
||||
JSObject *dataArray = JS_NewArrayObject(ctx, w*h*4, jsvector.get());
|
||||
if (!dataArray)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
nsAutoGCRoot arrayGCRoot(&dataArray, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Allocate result object after array, so if we have to trigger gc
|
||||
// we do it now.
|
||||
JSObject *result = JS_NewObject(ctx, NULL, NULL, NULL);
|
||||
if (!result)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
@ -3534,13 +3449,6 @@ nsCanvasRenderingContext2D::GetImageData()
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
#include "jstypes.h"
|
||||
JS_FRIEND_API(JSBool)
|
||||
js_CoerceArrayToCanvasImageData(JSObject *obj, jsuint offset, jsuint count,
|
||||
JSUint8 *dest);
|
||||
}
|
||||
|
||||
static inline PRUint8 ToUint8(jsint aInput)
|
||||
{
|
||||
if (PRUint32(aInput) > 255)
|
||||
|
@ -3806,21 +3714,19 @@ nsCanvasRenderingContext2D::CreateImageData()
|
|||
if (len / 4 != len0)
|
||||
return NS_ERROR_DOM_INDEX_SIZE_ERR;
|
||||
|
||||
nsAutoArrayPtr<jsval> jsvector(new (std::nothrow) jsval[w * h * 4]);
|
||||
if (!jsvector)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
jsval *dest = jsvector.get();
|
||||
for (PRUint32 i = 0; i < len; i++)
|
||||
*dest++ = JSVAL_ZERO;
|
||||
|
||||
JSObject *dataArray = JS_NewArrayObject(ctx, w*h*4, jsvector.get());
|
||||
jsval *dest;
|
||||
JSObject *dataArray = js_NewArrayObjectWithCapacity(ctx, len, &dest);
|
||||
if (!dataArray)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
nsAutoGCRoot arrayGCRoot(&dataArray, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
for (PRUint32 i = 0; i < len; i++)
|
||||
*dest++ = JSVAL_ZERO;
|
||||
|
||||
// Allocate result object after array, so if we have to trigger gc
|
||||
// we do it now.
|
||||
JSObject *result = JS_NewObject(ctx, NULL, NULL, NULL);
|
||||
if (!result)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
|
|
@ -3649,18 +3649,20 @@ isPixel(ctx, 50,25, 0,255,0,255, 2);
|
|||
|
||||
function test_2d_drawImage_wrongtype() {
|
||||
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
|
||||
var canvas = document.getElementById('c127');
|
||||
var ctx = canvas.getContext('2d');
|
||||
|
||||
var _thrown = undefined; try {
|
||||
ctx.drawImage(undefined, 0, 0);
|
||||
} catch (e) { _thrown = e }; ok(_thrown && _thrown.code == DOMException.TYPE_MISMATCH_ERR, "should throw TYPE_MISMATCH_ERR");
|
||||
} catch (e) { _thrown = e }; ok(_thrown && _thrown.result == Components.results.NS_ERROR_INVALID_ARG, "should throw NS_ERROR_INVALID_ARG");
|
||||
var _thrown = undefined; try {
|
||||
ctx.drawImage(0, 0, 0);
|
||||
} catch (e) { _thrown = e }; ok(_thrown && _thrown.code == DOMException.TYPE_MISMATCH_ERR, "should throw TYPE_MISMATCH_ERR");
|
||||
} catch (e) { _thrown = e }; ok(_thrown && _thrown.result == Components.results.NS_ERROR_XPC_BAD_CONVERT_JS_ZERO_ISNOT_NULL, "should throw NS_ERROR_XPC_BAD_CONVERT_JS_ZERO_ISNOT_NULL");
|
||||
var _thrown = undefined; try {
|
||||
ctx.drawImage("", 0, 0);
|
||||
} catch (e) { _thrown = e }; ok(_thrown && _thrown.code == DOMException.TYPE_MISMATCH_ERR, "should throw TYPE_MISMATCH_ERR");
|
||||
} catch (e) { _thrown = e }; ok(_thrown && _thrown.result == Components.results.NS_ERROR_XPC_BAD_CONVERT_JS, "should throw NS_ERROR_XPC_BAD_CONVERT_JS");
|
||||
var _thrown = undefined; try {
|
||||
ctx.drawImage(document.createElement('p'), 0, 0);
|
||||
} catch (e) { _thrown = e }; todo(_thrown && _thrown.code == DOMException.TYPE_MISMATCH_ERR, "should throw TYPE_MISMATCH_ERR");
|
||||
|
@ -7352,8 +7354,8 @@ var _thrown_outer = false;
|
|||
|
||||
var imgdata1 = ctx.createImageData(10.01, 10.99);
|
||||
var imgdata2 = ctx.getImageData(0, 0, 10.01, 10.99);
|
||||
ok(imgdata1.width == imgdata2.width, "imgdata1.width == imgdata2.width");
|
||||
ok(imgdata1.height == imgdata2.height, "imgdata1.height == imgdata2.height");
|
||||
is(imgdata1.width, imgdata2.width, "imgdata1.width == imgdata2.width");
|
||||
is(imgdata1.height, imgdata2.height, "imgdata1.height == imgdata2.height");
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -459,7 +459,23 @@ nsDOMEvent::PreventDefault()
|
|||
{
|
||||
if (!(mEvent->flags & NS_EVENT_FLAG_CANT_CANCEL)) {
|
||||
mEvent->flags |= NS_EVENT_FLAG_NO_DEFAULT;
|
||||
|
||||
// Need to set an extra flag for drag events.
|
||||
if (mEvent->eventStructType == NS_DRAG_EVENT &&
|
||||
NS_IS_TRUSTED_EVENT(mEvent)) {
|
||||
nsCOMPtr<nsINode> node = do_QueryInterface(mEvent->currentTarget);
|
||||
if (!node) {
|
||||
nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(mEvent->currentTarget);
|
||||
if (win) {
|
||||
node = do_QueryInterface(win->GetExtantDocument());
|
||||
}
|
||||
}
|
||||
if (node && !nsContentUtils::IsChromeDoc(node->GetOwnerDoc())) {
|
||||
mEvent->flags |= NS_EVENT_FLAG_NO_DEFAULT_CALLED_IN_CONTENT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -46,6 +46,8 @@
|
|||
#include "nsMutationEvent.h"
|
||||
#include NEW_H
|
||||
#include "nsFixedSizeAllocator.h"
|
||||
#include "nsINode.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
|
||||
#define NS_TARGET_CHAIN_FORCE_CONTENT_DISPATCH (1 << 0)
|
||||
#define NS_TARGET_CHAIN_WANTS_WILL_HANDLE_EVENT (1 << 1)
|
||||
|
@ -444,6 +446,28 @@ nsEventDispatcher::Dispatch(nsISupports* aTarget,
|
|||
NS_ERROR_ILLEGAL_VALUE);
|
||||
NS_ASSERTION(!aTargets || !aEvent->message, "Wrong parameters!");
|
||||
|
||||
if (aEvent->flags & NS_EVENT_FLAG_ONLY_CHROME_DISPATCH) {
|
||||
nsCOMPtr<nsINode> node = do_QueryInterface(aTarget);
|
||||
if (!node) {
|
||||
nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(aTarget);
|
||||
if (win) {
|
||||
node = do_QueryInterface(win->GetExtantDocument());
|
||||
}
|
||||
}
|
||||
|
||||
NS_ENSURE_STATE(node);
|
||||
nsIDocument* doc = node->GetOwnerDoc();
|
||||
if (!nsContentUtils::IsChromeDoc(doc)) {
|
||||
nsPIDOMWindow* win = doc ? doc->GetInnerWindow() : nsnull;
|
||||
// If we can't dispatch the event to chrome, do nothing.
|
||||
NS_ENSURE_TRUE(win && win->GetChromeEventHandler(), NS_OK);
|
||||
// Set the target to be the original dispatch target,
|
||||
aEvent->target = aTarget;
|
||||
// but use chrome event handler for event target chain.
|
||||
aTarget = win->GetChromeEventHandler();
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMEventTarget> target = do_QueryInterface(aTarget);
|
||||
#ifdef DEBUG
|
||||
if (aDOMEvent) {
|
||||
|
|
|
@ -3042,6 +3042,13 @@ nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext,
|
|||
if (!dragSession)
|
||||
break;
|
||||
|
||||
// Reset the flag.
|
||||
dragSession->SetOnlyChromeDrop(PR_FALSE);
|
||||
if (mPresContext) {
|
||||
EnsureDocument(mPresContext);
|
||||
}
|
||||
PRBool isChromeDoc = nsContentUtils::IsChromeDoc(mDocument);
|
||||
|
||||
// the initial dataTransfer is the one from the dragstart event that
|
||||
// was set on the dragSession when the drag began.
|
||||
nsCOMPtr<nsIDOMNSDataTransfer> dataTransfer;
|
||||
|
@ -3117,6 +3124,16 @@ nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext,
|
|||
// inform the drag session that a drop is allowed on this node.
|
||||
dragSession->SetDragAction(action);
|
||||
dragSession->SetCanDrop(action != nsIDragService::DRAGDROP_ACTION_NONE);
|
||||
|
||||
// For now, do this only for dragover.
|
||||
//XXXsmaug dragenter needs some more work.
|
||||
if (aEvent->message == NS_DRAGDROP_OVER && !isChromeDoc) {
|
||||
// Someone has called preventDefault(), check whether is was content.
|
||||
dragSession->SetOnlyChromeDrop(
|
||||
!(aEvent->flags & NS_EVENT_FLAG_NO_DEFAULT_CALLED_IN_CONTENT));
|
||||
}
|
||||
} else if (aEvent->message == NS_DRAGDROP_OVER && !isChromeDoc) {
|
||||
dragSession->SetCanDrop(PR_FALSE);
|
||||
}
|
||||
|
||||
// now set the drop effect in the initial dataTransfer. This ensures
|
||||
|
|
|
@ -80,6 +80,7 @@ _TEST_FILES = \
|
|||
test_bug489671.html \
|
||||
test_bug493251.html \
|
||||
test_bug502818.html \
|
||||
test_bug508479.html \
|
||||
test_bug517851.html \
|
||||
$(NULL)
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ function setOrRestoreTabFocus(newValue) {
|
|||
const prefSvcIID = Components.interfaces.nsIPrefService;
|
||||
var prefs = Components.classes[prefSvcContractID].getService(prefSvcIID)
|
||||
.getBranch("accessibility.");
|
||||
if (!newValue) {
|
||||
if (!newValue && prefs.prefHasUserValue("tabfocus")) {
|
||||
prefs.clearUserPref("tabfocus");
|
||||
} else {
|
||||
prefs.setIntPref("tabfocus", newValue);
|
||||
|
|
|
@ -41,7 +41,9 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=238987
|
|||
var prefs = Components.classes[prefSvcContractID].getService(prefSvcIID)
|
||||
.getBranch("accessibility.");
|
||||
if (!newValue) {
|
||||
prefs.clearUserPref("tabfocus");
|
||||
try {
|
||||
prefs.clearUserPref("tabfocus");
|
||||
} catch(ex) {}
|
||||
} else {
|
||||
prefs.setIntPref("tabfocus", newValue);
|
||||
}
|
||||
|
|
|
@ -237,8 +237,10 @@ function clearPrefs()
|
|||
var prefSvc = Components.classes["@mozilla.org/preferences-service;1"].
|
||||
getService(Components.interfaces.nsIPrefBranch2);
|
||||
|
||||
prefSvc.clearUserPref("mousewheel.acceleration.start");
|
||||
prefSvc.clearUserPref("mousewheel.system_scroll_override_on_root_content.enabled");
|
||||
if (prefSvc.prefHasUserValue("mousewheel.acceleration.start"))
|
||||
prefSvc.clearUserPref("mousewheel.acceleration.start");
|
||||
if (prefSvc.prefHasUserValue("mousewheel.system_scroll_override_on_root_content.enabled"))
|
||||
prefSvc.clearUserPref("mousewheel.system_scroll_override_on_root_content.enabled");
|
||||
}
|
||||
|
||||
window.onload = function () {
|
||||
|
|
|
@ -104,7 +104,9 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=409604
|
|||
var prefs = Components.classes[prefSvcContractID].getService(prefSvcIID)
|
||||
.getBranch("ui.key.");
|
||||
if (!newValue) {
|
||||
prefs.clearUserPref("contentAccess");
|
||||
try {
|
||||
prefs.clearUserPref("contentAccess");
|
||||
} catch(ex) {}
|
||||
} else {
|
||||
prefs.setIntPref("contentAccess", newValue);
|
||||
}
|
||||
|
|
|
@ -29,7 +29,9 @@ function setUserPref(reset) {
|
|||
var prefs = Components.classes[prefSvcContractID].getService(prefSvcIID)
|
||||
.getBranch("browser.link.");
|
||||
if (reset) {
|
||||
prefs.clearUserPref("open_newwindow");
|
||||
try {
|
||||
prefs.clearUserPref("open_newwindow");
|
||||
} catch (ex) {}
|
||||
} else {
|
||||
prefs.setIntPref("open_newwindow", 3);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Tests for the dragstart event</title>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
|
||||
<script type="application/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
|
||||
<script>
|
||||
|
||||
var gGotHandlingDrop = false;
|
||||
var gGotNotHandlingDrop = false;
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
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, dragData, effectAllowed) {
|
||||
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 runTests()
|
||||
{
|
||||
var targetHandling = document.getElementById("handling_target");
|
||||
fireDrop(targetHandling, [{"test/plain": "Hello!"}]);
|
||||
|
||||
is(gGotHandlingDrop, true, "Got drop on accepting element (1)");
|
||||
is(gGotNotHandlingDrop, false, "Didn't get drop on unaccepting element (1)");
|
||||
|
||||
// reset
|
||||
gGotHandlingDrop = false;
|
||||
gGotNotHandlingDrop = false;
|
||||
|
||||
var targetNotHandling = document.getElementById("nothandling_target");
|
||||
fireDrop(targetNotHandling, [{"test/plain": "Hello!"}]);
|
||||
|
||||
is(gGotHandlingDrop, false, "Didn't get drop on accepting element (2)");
|
||||
is(gGotNotHandlingDrop, false, "Didn't get drop on unaccepting element (2)");
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<body onload="window.setTimeout(runTests, 0);">
|
||||
|
||||
<img style="width: 100px; height: 100px;"
|
||||
src="data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%18%00%00%00%18%02%03%00%00%00%9D%19%D5k%00%00%00%04gAMA%00%00%B1%8F%0B%FCa%05%00%00%00%0CPLTE%FF%FF%FF%FF%FF%FF%F7%DC%13%00%00%00%03%80%01X%00%00%00%01tRNS%08N%3DPT%00%00%00%01bKGD%00%88%05%1DH%00%00%00%09pHYs%00%00%0B%11%00%00%0B%11%01%7Fd_%91%00%00%00%07tIME%07%D2%05%0C%14%0C%0D%D8%3F%1FQ%00%00%00%5CIDATx%9C%7D%8E%CB%09%C0%20%10D%07r%B7%20%2F%E9wV0%15h%EA%D9%12D4%BB%C1x%CC%5C%1E%0C%CC%07%C0%9C0%9Dd7()%C0A%D3%8D%E0%B8%10%1DiCHM%D0%AC%D2d%C3M%F1%B4%E7%FF%10%0BY%AC%25%93%CD%CBF%B5%B2%C0%3Alh%CD%AE%13%DF%A5%F7%E0%03byW%09A%B4%F3%E2%00%00%00%00IEND%AEB%60%82"
|
||||
id="handling_target"
|
||||
ondragenter="event.preventDefault()"
|
||||
ondragover="event.preventDefault()"
|
||||
ondrop="gGotHandlingDrop = true;">
|
||||
|
||||
<img style="width: 100px; height: 100px;"
|
||||
src="data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%18%00%00%00%18%02%03%00%00%00%9D%19%D5k%00%00%00%04gAMA%00%00%B1%8F%0B%FCa%05%00%00%00%0CPLTE%FF%FF%FF%FF%FF%FF%F7%DC%13%00%00%00%03%80%01X%00%00%00%01tRNS%08N%3DPT%00%00%00%01bKGD%00%88%05%1DH%00%00%00%09pHYs%00%00%0B%11%00%00%0B%11%01%7Fd_%91%00%00%00%07tIME%07%D2%05%0C%14%0C%0D%D8%3F%1FQ%00%00%00%5CIDATx%9C%7D%8E%CB%09%C0%20%10D%07r%B7%20%2F%E9wV0%15h%EA%D9%12D4%BB%C1x%CC%5C%1E%0C%CC%07%C0%9C0%9Dd7()%C0A%D3%8D%E0%B8%10%1DiCHM%D0%AC%D2d%C3M%F1%B4%E7%FF%10%0BY%AC%25%93%CD%CBF%B5%B2%C0%3Alh%CD%AE%13%DF%A5%F7%E0%03byW%09A%B4%F3%E2%00%00%00%00IEND%AEB%60%82"
|
||||
id="nothandling_target"
|
||||
ondrop="gGotNotHandlingDrop = true;">
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -88,6 +88,8 @@ public:
|
|||
virtual nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
nsIAtom* aPrefix, const nsAString& aValue,
|
||||
PRBool aNotify);
|
||||
virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttr,
|
||||
PRBool aNotify);
|
||||
|
||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
|
@ -97,7 +99,12 @@ public:
|
|||
|
||||
virtual PRBool IsDoneAddingChildren();
|
||||
virtual nsresult DoneAddingChildren(PRBool aHaveNotified);
|
||||
virtual void DestroyContent();
|
||||
|
||||
/**
|
||||
* Call this to reevaluate whether we should start/stop due to our owner
|
||||
* document being active or inactive.
|
||||
*/
|
||||
void NotifyOwnerDocumentActivityChanged();
|
||||
|
||||
// Called by the video decoder object, on the main thread,
|
||||
// when it has read the metadata containing video dimensions,
|
||||
|
@ -180,6 +187,9 @@ public:
|
|||
// events can be fired.
|
||||
void ChangeReadyState(nsMediaReadyState aState);
|
||||
|
||||
// Return true if we can activate autoplay assuming enough data has arrived.
|
||||
PRBool CanActivateAutoplay();
|
||||
|
||||
// Notify that enough data has arrived to start autoplaying.
|
||||
// If the element is 'autoplay' and is ready to play back (not paused,
|
||||
// autoplay pref enabled, etc), it should start playing back.
|
||||
|
@ -204,11 +214,6 @@ public:
|
|||
// main thread when/if the size changes.
|
||||
void UpdateMediaSize(nsIntSize size);
|
||||
|
||||
// Handle moving into and out of the bfcache by pausing and playing
|
||||
// as needed.
|
||||
void Freeze();
|
||||
void Thaw();
|
||||
|
||||
// Returns true if we can handle this MIME type.
|
||||
// If it returns true, then it also returns a null-terminated list
|
||||
// of supported codecs in *aSupportedCodecs. This
|
||||
|
@ -277,10 +282,10 @@ protected:
|
|||
void SetPlayedOrSeeked(PRBool aValue);
|
||||
|
||||
/**
|
||||
* Create a decoder for the given aMIMEType. Returns false if we
|
||||
* Create a decoder for the given aMIMEType. Returns null if we
|
||||
* were unable to create the decoder.
|
||||
*/
|
||||
PRBool CreateDecoder(const nsACString& aMIMEType);
|
||||
already_AddRefed<nsMediaDecoder> CreateDecoder(const nsACString& aMIMEType);
|
||||
|
||||
/**
|
||||
* Initialize a decoder as a clone of an existing decoder in another
|
||||
|
@ -298,7 +303,7 @@ protected:
|
|||
/**
|
||||
* Finish setting up the decoder after Load() has been called on it.
|
||||
*/
|
||||
nsresult FinishDecoderSetup();
|
||||
nsresult FinishDecoderSetup(nsMediaDecoder* aDecoder);
|
||||
|
||||
/**
|
||||
* Execute the initial steps of the load algorithm that ensure existing
|
||||
|
@ -371,6 +376,18 @@ protected:
|
|||
nsIChannel *aNewChannel,
|
||||
PRUint32 aFlags);
|
||||
|
||||
/**
|
||||
* Call this to reevaluate whether we should be holding a self-reference.
|
||||
*/
|
||||
void AddRemoveSelfReference();
|
||||
|
||||
/**
|
||||
* Alias for Release(), but using stdcall calling convention so on
|
||||
* platforms where Release has a strange calling convention (Windows)
|
||||
* we can still get a method pointer to this method.
|
||||
*/
|
||||
void DoRelease() { Release(); }
|
||||
|
||||
nsRefPtr<nsMediaDecoder> mDecoder;
|
||||
|
||||
// Holds a reference to the first channel we open to the media resource.
|
||||
|
@ -462,10 +479,8 @@ protected:
|
|||
// to raise the 'waiting' event as per 4.7.1.8 in HTML 5 specification.
|
||||
PRPackedBool mPlayingBeforeSeek;
|
||||
|
||||
// PR_TRUE if the video was paused before Freeze was called. This is checked
|
||||
// to ensure that the playstate doesn't change when the user goes Forward/Back
|
||||
// from the bfcache.
|
||||
PRPackedBool mPausedBeforeFreeze;
|
||||
// PR_TRUE iff this element is paused because the document is inactive
|
||||
PRPackedBool mPausedForInactiveDocument;
|
||||
|
||||
// PR_TRUE if we've reported a "waiting" event since the last
|
||||
// readyState change to HAVE_CURRENT_DATA.
|
||||
|
@ -499,4 +514,9 @@ protected:
|
|||
// PR_TRUE if we've played or completed a seek. We use this to determine
|
||||
// when the poster frame should be shown.
|
||||
PRPackedBool mHasPlayedOrSeeked;
|
||||
|
||||
// PR_TRUE if we've added a reference to ourselves to keep the element
|
||||
// alive while no-one is referencing it but the element may still fire
|
||||
// events of its own accord.
|
||||
PRPackedBool mHasSelfReference;
|
||||
};
|
||||
|
|
|
@ -721,7 +721,7 @@ nsGenericHTMLElement::SetInnerHTML(const nsAString& aInnerHTML)
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsGenericHTMLElement::ScrollIntoView(PRBool aTop)
|
||||
nsGenericHTMLElement::ScrollIntoView(PRBool aTop, PRUint8 optional_argc)
|
||||
{
|
||||
nsIDocument *document = GetCurrentDoc();
|
||||
|
||||
|
@ -735,6 +735,10 @@ nsGenericHTMLElement::ScrollIntoView(PRBool aTop)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!optional_argc) {
|
||||
aTop = PR_TRUE;
|
||||
}
|
||||
|
||||
PRIntn vpercent = aTop ? NS_PRESSHELL_SCROLL_TOP :
|
||||
NS_PRESSHELL_SCROLL_BOTTOM;
|
||||
|
||||
|
|
|
@ -142,7 +142,7 @@ public:
|
|||
nsresult GetOffsetParent(nsIDOMElement** aOffsetParent);
|
||||
virtual nsresult GetInnerHTML(nsAString& aInnerHTML);
|
||||
virtual nsresult SetInnerHTML(const nsAString& aInnerHTML);
|
||||
nsresult ScrollIntoView(PRBool aTop);
|
||||
nsresult ScrollIntoView(PRBool aTop, PRUint8 optional_argc);
|
||||
// Declare Focus(), Blur(), GetTabIndex(), SetTabIndex(), GetSpellcheck(),
|
||||
// SetSpellcheck(), and GetDraggable() such that classes that inherit interfaces
|
||||
// with those methods properly override them
|
||||
|
|
|
@ -295,66 +295,23 @@ nsHTMLCanvasElement::ParseAttribute(PRInt32 aNamespaceID,
|
|||
// nsHTMLCanvasElement::toDataURL
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLCanvasElement::ToDataURL(nsAString& aDataURL)
|
||||
nsHTMLCanvasElement::ToDataURL(const nsAString& aType, const nsAString& aParams,
|
||||
PRUint8 optional_argc, nsAString& aDataURL)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
nsAXPCNativeCallContext *ncc = nsnull;
|
||||
rv = nsContentUtils::XPConnect()->
|
||||
GetCurrentNativeCallContext(&ncc);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!ncc)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
JSContext *ctx = nsnull;
|
||||
|
||||
rv = ncc->GetJSContext(&ctx);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRUint32 argc;
|
||||
jsval *argv = nsnull;
|
||||
|
||||
ncc->GetArgc(&argc);
|
||||
ncc->GetArgvPtr(&argv);
|
||||
|
||||
// do a trust check if this is a write-only canvas
|
||||
// or if we're trying to use the 2-arg form
|
||||
if ((mWriteOnly || argc >= 2) && !nsContentUtils::IsCallerTrustedForRead()) {
|
||||
if ((mWriteOnly || optional_argc >= 2) &&
|
||||
!nsContentUtils::IsCallerTrustedForRead()) {
|
||||
return NS_ERROR_DOM_SECURITY_ERR;
|
||||
}
|
||||
|
||||
// 0-arg case; convert to png
|
||||
if (argc == 0) {
|
||||
return ToDataURLImpl(NS_LITERAL_STRING("image/png"), EmptyString(), aDataURL);
|
||||
nsAutoString type(aType);
|
||||
|
||||
if (type.IsEmpty()) {
|
||||
type.AssignLiteral("image/png");
|
||||
}
|
||||
|
||||
JSAutoRequest ar(ctx);
|
||||
|
||||
// 1-arg case; convert to given mime type
|
||||
if (argc == 1) {
|
||||
if (!JSVAL_IS_STRING(argv[0]))
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
JSString *type = JS_ValueToString(ctx, argv[0]);
|
||||
return ToDataURLImpl (nsDependentString(reinterpret_cast<PRUnichar*>((JS_GetStringChars(type)))),
|
||||
EmptyString(), aDataURL);
|
||||
}
|
||||
|
||||
// 2-arg case; trusted only (checked above), convert to mime type with params
|
||||
if (argc == 2) {
|
||||
if (!JSVAL_IS_STRING(argv[0]) || !JSVAL_IS_STRING(argv[1]))
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
|
||||
JSString *type, *params;
|
||||
type = JS_ValueToString(ctx, argv[0]);
|
||||
params = JS_ValueToString(ctx, argv[1]);
|
||||
|
||||
return ToDataURLImpl (nsDependentString(reinterpret_cast<PRUnichar*>(JS_GetStringChars(type))),
|
||||
nsDependentString(reinterpret_cast<PRUnichar*>(JS_GetStringChars(params))),
|
||||
aDataURL);
|
||||
}
|
||||
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
return ToDataURLImpl(type, aParams, aDataURL);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -331,6 +331,11 @@ protected:
|
|||
nsITextControlFrame* aFrame,
|
||||
PRBool aUserInput);
|
||||
|
||||
void ClearFileNames() {
|
||||
nsTArray<nsString> fileNames;
|
||||
SetFileNames(fileNames);
|
||||
}
|
||||
|
||||
void SetSingleFileName(const nsAString& aFileName) {
|
||||
nsAutoTArray<nsString, 1> fileNames;
|
||||
fileNames.AppendElement(aFileName);
|
||||
|
@ -912,8 +917,11 @@ nsHTMLInputElement::SetValue(const nsAString& aValue)
|
|||
// UniversalFileRead privilege
|
||||
return NS_ERROR_DOM_SECURITY_ERR;
|
||||
}
|
||||
SetSingleFileName(aValue);
|
||||
}
|
||||
else {
|
||||
ClearFileNames();
|
||||
}
|
||||
SetSingleFileName(aValue);
|
||||
}
|
||||
else {
|
||||
SetValueInternal(aValue, nsnull, PR_FALSE);
|
||||
|
@ -1007,7 +1015,11 @@ void
|
|||
nsHTMLInputElement::SetFileNames(const nsTArray<nsString>& aFileNames)
|
||||
{
|
||||
mFileNames = aFileNames;
|
||||
|
||||
#if DEBUG
|
||||
for (PRUint32 i = 0; i < (PRUint32)aFileNames.Length(); ++i) {
|
||||
NS_ASSERTION(!aFileNames[i].IsEmpty(), "Empty file name");
|
||||
}
|
||||
#endif
|
||||
// No need to flush here, if there's no frame at this point we
|
||||
// don't need to force creation of one just to tell it about this
|
||||
// new value. We just want the display to update as needed.
|
||||
|
@ -2161,14 +2173,11 @@ nsHTMLInputElement::ParseAttribute(PRInt32 aNamespaceID,
|
|||
// makes assumptions about our frame based on mType, but we won't have
|
||||
// had time to recreate frames yet -- that happens later in the
|
||||
// SetAttr() process).
|
||||
if (newType == NS_FORM_INPUT_FILE) {
|
||||
// These calls aren't strictly needed any more since we'll never
|
||||
// confuse values and filenames. However they're there for backwards
|
||||
if (newType == NS_FORM_INPUT_FILE || mType == NS_FORM_INPUT_FILE) {
|
||||
// This call isn't strictly needed any more since we'll never
|
||||
// confuse values and filenames. However it's there for backwards
|
||||
// compat.
|
||||
SetSingleFileName(EmptyString());
|
||||
SetValueInternal(EmptyString(), nsnull, PR_FALSE);
|
||||
} else if (mType == NS_FORM_INPUT_FILE) {
|
||||
SetSingleFileName(EmptyString());
|
||||
ClearFileNames();
|
||||
}
|
||||
|
||||
mType = newType;
|
||||
|
@ -2519,7 +2528,7 @@ nsHTMLInputElement::Reset()
|
|||
case NS_FORM_INPUT_FILE:
|
||||
{
|
||||
// Resetting it to blank should not perform security check
|
||||
SetSingleFileName(EmptyString());
|
||||
ClearFileNames();
|
||||
break;
|
||||
}
|
||||
// Value is the same as defaultValue for hidden inputs
|
||||
|
|
|
@ -96,6 +96,48 @@ static PRLogModuleInfo* gMediaElementEventsLog;
|
|||
#define LOG_EVENT(type, msg)
|
||||
#endif
|
||||
|
||||
// Under certain conditions there may be no-one holding references to
|
||||
// a media element from script, DOM parent, etc, but the element may still
|
||||
// fire meaningful events in the future so we can't destroy it yet:
|
||||
// 1) If the element is delaying the load event (or would be, if it were
|
||||
// in a document), then events up to loadeddata or error could be fired,
|
||||
// so we need to stay alive.
|
||||
// 2) If the element is not paused and playback has not ended, then
|
||||
// we will (or might) play, sending timeupdate and ended events and possibly
|
||||
// audio output, so we need to stay alive.
|
||||
// 3) if the element is seeking then we will fire seeking events and possibly
|
||||
// start playing afterward, so we need to stay alive.
|
||||
// 4) If autoplay could start playback in this element (if we got enough data),
|
||||
// then we need to stay alive.
|
||||
// 5) if the element is currently loading and not suspended,
|
||||
// script might be waiting for progress events or a 'suspend' event,
|
||||
// so we need to stay alive. If we're already suspended then (all other
|
||||
// conditions being met) it's OK to just disappear without firing any more
|
||||
// events, since we have the freedom to remain suspended indefinitely. Note
|
||||
// that we could use this 'suspended' loophole to garbage-collect a suspended
|
||||
// element in case 4 even if it had 'autoplay' set, but we choose not to.
|
||||
// If someone throws away all references to a loading 'autoplay' element
|
||||
// sound should still eventually play.
|
||||
//
|
||||
// Media elements owned by inactive documents (i.e. documents not contained in any
|
||||
// document viewer) should never hold a self-reference because none of the
|
||||
// above conditions are allowed: the element will stop loading and playing
|
||||
// and never resume loading or playing unless its owner document changes to
|
||||
// an active document (which can only happen if there is an external reference
|
||||
// to the element).
|
||||
// Media elements with no owner doc should be able to hold a self-reference.
|
||||
// Something native must have created the element and may expect it to
|
||||
// stay alive to play.
|
||||
|
||||
// It's very important that any change in state which could change the value of
|
||||
// needSelfReference in AddRemoveSelfReference be followed by a call to
|
||||
// AddRemoveSelfReference before this element could die!
|
||||
// It's especially important if needSelfReference would change to 'true',
|
||||
// since if we neglect to add a self-reference, this element might be
|
||||
// garbage collected while there are still event listeners that should
|
||||
// receive events. If we neglect to remove the self-reference then the element
|
||||
// just lives longer than it needs to.
|
||||
|
||||
class nsMediaEvent : public nsRunnable
|
||||
{
|
||||
public:
|
||||
|
@ -414,14 +456,21 @@ void nsHTMLMediaElement::AbortExistingLoads()
|
|||
DispatchSimpleEvent(NS_LITERAL_STRING("emptied"));
|
||||
}
|
||||
|
||||
// We may have changed mPaused, mAutoplaying, mNetworkState and other
|
||||
// things which can affect AddRemoveSelfReference
|
||||
AddRemoveSelfReference();
|
||||
|
||||
mIsRunningSelectResource = PR_FALSE;
|
||||
}
|
||||
|
||||
void nsHTMLMediaElement::NoSupportedMediaSourceError()
|
||||
{
|
||||
NS_ASSERTION(mDelayingLoadEvent, "Load event not delayed during source selection?");
|
||||
|
||||
mError = new nsHTMLMediaError(nsIDOMHTMLMediaError::MEDIA_ERR_SRC_NOT_SUPPORTED);
|
||||
mNetworkState = nsIDOMHTMLMediaElement::NETWORK_NO_SOURCE;
|
||||
DispatchAsyncProgressEvent(NS_LITERAL_STRING("error"));
|
||||
// This clears mDelayingLoadEvent, so AddRemoveSelfReference will be called
|
||||
ChangeDelayLoadStatus(PR_FALSE);
|
||||
}
|
||||
|
||||
|
@ -465,16 +514,21 @@ static PRBool HasPotentialResource(nsIContent *aElement)
|
|||
|
||||
void nsHTMLMediaElement::SelectResource()
|
||||
{
|
||||
NS_ASSERTION(mDelayingLoadEvent, "Load event not delayed during resource selection?");
|
||||
|
||||
if (!HasPotentialResource(this)) {
|
||||
// While the media element has neither a src attribute nor any source
|
||||
// element children, wait. (This steps might wait forever.)
|
||||
mNetworkState = nsIDOMHTMLMediaElement::NETWORK_NO_SOURCE;
|
||||
mLoadWaitStatus = WAITING_FOR_SRC_OR_SOURCE;
|
||||
// This clears mDelayingLoadEvent, so AddRemoveSelfReference will be called
|
||||
ChangeDelayLoadStatus(PR_FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
mNetworkState = nsIDOMHTMLMediaElement::NETWORK_LOADING;
|
||||
// Load event was delayed, and still is, so no need to call
|
||||
// AddRemoveSelfReference, since it must still be held
|
||||
DispatchAsyncProgressEvent(NS_LITERAL_STRING("loadstart"));
|
||||
|
||||
nsAutoString src;
|
||||
|
@ -508,8 +562,8 @@ void nsHTMLMediaElement::NotifyLoadError()
|
|||
|
||||
void nsHTMLMediaElement::LoadFromSourceChildren()
|
||||
{
|
||||
NS_ASSERTION(!IsInDoc() || mDelayingLoadEvent,
|
||||
"Should delay load event while loading in document");
|
||||
NS_ASSERTION(mDelayingLoadEvent,
|
||||
"Should delay load event (if in document) during load");
|
||||
while (PR_TRUE) {
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIURI> uri = GetNextSource();
|
||||
|
@ -534,8 +588,8 @@ void nsHTMLMediaElement::LoadFromSourceChildren()
|
|||
|
||||
nsresult nsHTMLMediaElement::LoadResource(nsIURI* aURI)
|
||||
{
|
||||
NS_ASSERTION(!IsInDoc() || mDelayingLoadEvent,
|
||||
"Should delay load event while loading in document");
|
||||
NS_ASSERTION(mDelayingLoadEvent,
|
||||
"Should delay load event (if in document) during load");
|
||||
nsresult rv;
|
||||
|
||||
if (mChannel) {
|
||||
|
@ -721,6 +775,10 @@ NS_IMETHODIMP nsHTMLMediaElement::SetCurrentTime(float aCurrentTime)
|
|||
// event if it changes the playback position as a result of the seek.
|
||||
LOG(PR_LOG_DEBUG, ("%p SetCurrentTime(%f) starting seek", this, aCurrentTime));
|
||||
nsresult rv = mDecoder->Seek(clampedTime);
|
||||
|
||||
// We changed whether we're seeking so we need to AddRemoveSelfReference
|
||||
AddRemoveSelfReference();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -752,6 +810,8 @@ NS_IMETHODIMP nsHTMLMediaElement::Pause()
|
|||
PRBool oldPaused = mPaused;
|
||||
mPaused = PR_TRUE;
|
||||
mAutoplaying = PR_FALSE;
|
||||
// We changed mPaused and mAutoplaying which can affect AddRemoveSelfReference
|
||||
AddRemoveSelfReference();
|
||||
|
||||
if (!oldPaused) {
|
||||
DispatchAsyncSimpleEvent(NS_LITERAL_STRING("timeupdate"));
|
||||
|
@ -827,7 +887,7 @@ nsHTMLMediaElement::nsHTMLMediaElement(nsINodeInfo *aNodeInfo, PRBool aFromParse
|
|||
mMuted(PR_FALSE),
|
||||
mIsDoneAddingChildren(!aFromParser),
|
||||
mPlayingBeforeSeek(PR_FALSE),
|
||||
mPausedBeforeFreeze(PR_FALSE),
|
||||
mPausedForInactiveDocument(PR_FALSE),
|
||||
mWaitingFired(PR_FALSE),
|
||||
mIsBindingToTree(PR_FALSE),
|
||||
mIsRunningLoadMethod(PR_FALSE),
|
||||
|
@ -836,7 +896,8 @@ nsHTMLMediaElement::nsHTMLMediaElement(nsINodeInfo *aNodeInfo, PRBool aFromParse
|
|||
mIsRunningSelectResource(PR_FALSE),
|
||||
mSuspendedAfterFirstFrame(PR_FALSE),
|
||||
mAllowSuspendAfterFirstFrame(PR_TRUE),
|
||||
mHasPlayedOrSeeked(PR_FALSE)
|
||||
mHasPlayedOrSeeked(PR_FALSE),
|
||||
mHasSelfReference(PR_FALSE)
|
||||
{
|
||||
#ifdef PR_LOGGING
|
||||
if (!gMediaElementLog) {
|
||||
|
@ -848,10 +909,14 @@ nsHTMLMediaElement::nsHTMLMediaElement(nsINodeInfo *aNodeInfo, PRBool aFromParse
|
|||
#endif
|
||||
|
||||
RegisterFreezableElement();
|
||||
NotifyOwnerDocumentActivityChanged();
|
||||
}
|
||||
|
||||
nsHTMLMediaElement::~nsHTMLMediaElement()
|
||||
{
|
||||
NS_ASSERTION(!mHasSelfReference,
|
||||
"How can we be destroyed if we're still holding a self reference?");
|
||||
|
||||
UnregisterFreezableElement();
|
||||
if (mDecoder) {
|
||||
mDecoder->Shutdown();
|
||||
|
@ -905,8 +970,10 @@ NS_IMETHODIMP nsHTMLMediaElement::Play()
|
|||
if (mDecoder->IsEnded()) {
|
||||
SetCurrentTime(0);
|
||||
}
|
||||
nsresult rv = mDecoder->Play();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!mPausedForInactiveDocument) {
|
||||
nsresult rv = mDecoder->Play();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: If the playback has ended, then the user agent must set
|
||||
|
@ -928,6 +995,8 @@ NS_IMETHODIMP nsHTMLMediaElement::Play()
|
|||
|
||||
mPaused = PR_FALSE;
|
||||
mAutoplaying = PR_FALSE;
|
||||
// We changed mPaused and mAutoplaying which can affect AddRemoveSelfReference
|
||||
AddRemoveSelfReference();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -979,6 +1048,8 @@ nsresult nsHTMLMediaElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
|||
if (mReadyState == nsIDOMHTMLMediaElement::HAVE_ENOUGH_DATA) {
|
||||
NotifyAutoplayDataReady();
|
||||
}
|
||||
// This attribute can affect AddRemoveSelfReference
|
||||
AddRemoveSelfReference();
|
||||
} else if (aName == nsGkAtoms::autobuffer) {
|
||||
StopSuspendingAfterFirstFrame();
|
||||
}
|
||||
|
@ -987,6 +1058,22 @@ nsresult nsHTMLMediaElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
|||
return rv;
|
||||
}
|
||||
|
||||
nsresult nsHTMLMediaElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttr,
|
||||
PRBool aNotify)
|
||||
{
|
||||
nsresult rv = nsGenericHTMLElement::UnsetAttr(aNameSpaceID, aAttr, aNotify);
|
||||
if (aNotify && aNameSpaceID == kNameSpaceID_None) {
|
||||
if (aAttr == nsGkAtoms::autoplay) {
|
||||
// This attribute can affect AddRemoveSelfReference
|
||||
AddRemoveSelfReference();
|
||||
}
|
||||
// We perhaps should stop loading if 'autobuffer' is being removed,
|
||||
// and we're buffering only because of 'autobuffer', but why bother?
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static PRBool IsAutoplayEnabled()
|
||||
{
|
||||
return nsContentUtils::GetBoolPref("media.autoplay.enabled");
|
||||
|
@ -1227,25 +1314,26 @@ void nsHTMLMediaElement::ShutdownMediaTypes()
|
|||
}
|
||||
}
|
||||
|
||||
PRBool nsHTMLMediaElement::CreateDecoder(const nsACString& aType)
|
||||
already_AddRefed<nsMediaDecoder>
|
||||
nsHTMLMediaElement::CreateDecoder(const nsACString& aType)
|
||||
{
|
||||
#ifdef MOZ_OGG
|
||||
if (IsOggType(aType)) {
|
||||
mDecoder = new nsOggDecoder();
|
||||
if (mDecoder && !mDecoder->Init(this)) {
|
||||
mDecoder = nsnull;
|
||||
nsRefPtr<nsOggDecoder> decoder = new nsOggDecoder();
|
||||
if (decoder && decoder->Init(this)) {
|
||||
return decoder.forget().get();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef MOZ_WAVE
|
||||
if (IsWaveType(aType)) {
|
||||
mDecoder = new nsWaveDecoder();
|
||||
if (mDecoder && !mDecoder->Init(this)) {
|
||||
mDecoder = nsnull;
|
||||
nsRefPtr<nsWaveDecoder> decoder = new nsWaveDecoder();
|
||||
if (decoder && decoder->Init(this)) {
|
||||
return decoder.forget().get();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return mDecoder != nsnull;
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsresult nsHTMLMediaElement::InitializeDecoderAsClone(nsMediaDecoder* aOriginal)
|
||||
|
@ -1253,38 +1341,35 @@ nsresult nsHTMLMediaElement::InitializeDecoderAsClone(nsMediaDecoder* aOriginal)
|
|||
nsMediaStream* originalStream = aOriginal->GetCurrentStream();
|
||||
if (!originalStream)
|
||||
return NS_ERROR_FAILURE;
|
||||
mDecoder = aOriginal->Clone();
|
||||
if (!mDecoder)
|
||||
nsRefPtr<nsMediaDecoder> decoder = aOriginal->Clone();
|
||||
if (!decoder)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
LOG(PR_LOG_DEBUG, ("%p Cloned decoder %p from %p", this, mDecoder.get(), aOriginal));
|
||||
LOG(PR_LOG_DEBUG, ("%p Cloned decoder %p from %p", this, decoder.get(), aOriginal));
|
||||
|
||||
if (!mDecoder->Init(this)) {
|
||||
mDecoder = nsnull;
|
||||
if (!decoder->Init(this)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
float duration = aOriginal->GetDuration();
|
||||
if (duration >= 0) {
|
||||
mDecoder->SetDuration(PRInt64(NS_round(duration * 1000)));
|
||||
mDecoder->SetSeekable(aOriginal->GetSeekable());
|
||||
decoder->SetDuration(PRInt64(NS_round(duration * 1000)));
|
||||
decoder->SetSeekable(aOriginal->GetSeekable());
|
||||
}
|
||||
|
||||
nsMediaStream* stream = originalStream->CloneData(mDecoder);
|
||||
nsMediaStream* stream = originalStream->CloneData(decoder);
|
||||
if (!stream) {
|
||||
mDecoder = nsnull;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mNetworkState = nsIDOMHTMLMediaElement::NETWORK_LOADING;
|
||||
|
||||
nsresult rv = mDecoder->Load(stream, nsnull);
|
||||
nsresult rv = decoder->Load(stream, nsnull);
|
||||
if (NS_FAILED(rv)) {
|
||||
mDecoder = nsnull;
|
||||
return rv;
|
||||
}
|
||||
|
||||
return FinishDecoderSetup();
|
||||
return FinishDecoderSetup(decoder);
|
||||
}
|
||||
|
||||
nsresult nsHTMLMediaElement::InitializeDecoderForChannel(nsIChannel *aChannel,
|
||||
|
@ -1293,20 +1378,21 @@ nsresult nsHTMLMediaElement::InitializeDecoderForChannel(nsIChannel *aChannel,
|
|||
nsCAutoString mimeType;
|
||||
aChannel->GetContentType(mimeType);
|
||||
|
||||
if (!CreateDecoder(mimeType))
|
||||
nsRefPtr<nsMediaDecoder> decoder = CreateDecoder(mimeType);
|
||||
if (!decoder) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
LOG(PR_LOG_DEBUG, ("%p Created decoder %p for type %s", this, mDecoder.get(), mimeType.get()));
|
||||
LOG(PR_LOG_DEBUG, ("%p Created decoder %p for type %s", this, decoder.get(), mimeType.get()));
|
||||
|
||||
mNetworkState = nsIDOMHTMLMediaElement::NETWORK_LOADING;
|
||||
|
||||
nsMediaStream* stream = nsMediaStream::Create(mDecoder, aChannel);
|
||||
nsMediaStream* stream = nsMediaStream::Create(decoder, aChannel);
|
||||
if (!stream)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
nsresult rv = mDecoder->Load(stream, aListener);
|
||||
nsresult rv = decoder->Load(stream, aListener);
|
||||
if (NS_FAILED(rv)) {
|
||||
mDecoder = nsnull;
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -1314,18 +1400,28 @@ nsresult nsHTMLMediaElement::InitializeDecoderForChannel(nsIChannel *aChannel,
|
|||
// which owns the channel.
|
||||
mChannel = nsnull;
|
||||
|
||||
return FinishDecoderSetup();
|
||||
return FinishDecoderSetup(decoder);
|
||||
}
|
||||
|
||||
nsresult nsHTMLMediaElement::FinishDecoderSetup()
|
||||
nsresult nsHTMLMediaElement::FinishDecoderSetup(nsMediaDecoder* aDecoder)
|
||||
{
|
||||
mDecoder = aDecoder;
|
||||
|
||||
// The new stream has not been suspended by us.
|
||||
mPausedForInactiveDocument = PR_FALSE;
|
||||
// But we may want to suspend it now.
|
||||
// This will also do an AddRemoveSelfReference.
|
||||
NotifyOwnerDocumentActivityChanged();
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
mDecoder->SetVolume(mMuted ? 0.0 : mVolume);
|
||||
|
||||
if (!mPaused) {
|
||||
SetPlayedOrSeeked(PR_TRUE);
|
||||
rv = mDecoder->Play();
|
||||
if (!mPausedForInactiveDocument) {
|
||||
rv = mDecoder->Play();
|
||||
}
|
||||
}
|
||||
|
||||
mBegun = PR_TRUE;
|
||||
|
@ -1393,6 +1489,7 @@ void nsHTMLMediaElement::ResourceLoaded()
|
|||
{
|
||||
mBegun = PR_FALSE;
|
||||
mNetworkState = nsIDOMHTMLMediaElement::NETWORK_IDLE;
|
||||
AddRemoveSelfReference();
|
||||
ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_ENOUGH_DATA);
|
||||
// The download has stopped
|
||||
DispatchAsyncSimpleEvent(NS_LITERAL_STRING("suspend"));
|
||||
|
@ -1404,6 +1501,7 @@ void nsHTMLMediaElement::NetworkError()
|
|||
mBegun = PR_FALSE;
|
||||
DispatchAsyncProgressEvent(NS_LITERAL_STRING("error"));
|
||||
mNetworkState = nsIDOMHTMLMediaElement::NETWORK_EMPTY;
|
||||
AddRemoveSelfReference();
|
||||
DispatchAsyncSimpleEvent(NS_LITERAL_STRING("emptied"));
|
||||
ChangeDelayLoadStatus(PR_FALSE);
|
||||
}
|
||||
|
@ -1414,6 +1512,7 @@ void nsHTMLMediaElement::DecodeError()
|
|||
mBegun = PR_FALSE;
|
||||
DispatchAsyncProgressEvent(NS_LITERAL_STRING("error"));
|
||||
mNetworkState = nsIDOMHTMLMediaElement::NETWORK_EMPTY;
|
||||
AddRemoveSelfReference();
|
||||
DispatchAsyncSimpleEvent(NS_LITERAL_STRING("emptied"));
|
||||
ChangeDelayLoadStatus(PR_FALSE);
|
||||
}
|
||||
|
@ -1421,6 +1520,9 @@ void nsHTMLMediaElement::DecodeError()
|
|||
void nsHTMLMediaElement::PlaybackEnded()
|
||||
{
|
||||
NS_ASSERTION(mDecoder->IsEnded(), "Decoder fired ended, but not in ended state");
|
||||
// We changed the state of IsPlaybackEnded which can affect AddRemoveSelfReference
|
||||
AddRemoveSelfReference();
|
||||
|
||||
DispatchAsyncSimpleEvent(NS_LITERAL_STRING("ended"));
|
||||
}
|
||||
|
||||
|
@ -1434,12 +1536,15 @@ void nsHTMLMediaElement::SeekCompleted()
|
|||
mPlayingBeforeSeek = PR_FALSE;
|
||||
SetPlayedOrSeeked(PR_TRUE);
|
||||
DispatchAsyncSimpleEvent(NS_LITERAL_STRING("seeked"));
|
||||
// We changed whether we're seeking so we need to AddRemoveSelfReference
|
||||
AddRemoveSelfReference();
|
||||
}
|
||||
|
||||
void nsHTMLMediaElement::DownloadSuspended()
|
||||
{
|
||||
if (mBegun) {
|
||||
mNetworkState = nsIDOMHTMLMediaElement::NETWORK_IDLE;
|
||||
AddRemoveSelfReference();
|
||||
DispatchAsyncSimpleEvent(NS_LITERAL_STRING("suspend"));
|
||||
}
|
||||
}
|
||||
|
@ -1448,6 +1553,7 @@ void nsHTMLMediaElement::DownloadResumed()
|
|||
{
|
||||
if (mBegun) {
|
||||
mNetworkState = nsIDOMHTMLMediaElement::NETWORK_LOADING;
|
||||
AddRemoveSelfReference();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1578,13 +1684,21 @@ void nsHTMLMediaElement::ChangeReadyState(nsMediaReadyState aState)
|
|||
}
|
||||
}
|
||||
|
||||
PRBool nsHTMLMediaElement::CanActivateAutoplay()
|
||||
{
|
||||
return mAutoplaying &&
|
||||
mPaused &&
|
||||
HasAttr(kNameSpaceID_None, nsGkAtoms::autoplay) &&
|
||||
mAutoplayEnabled;
|
||||
}
|
||||
|
||||
void nsHTMLMediaElement::NotifyAutoplayDataReady()
|
||||
{
|
||||
if (mAutoplaying &&
|
||||
mPaused &&
|
||||
HasAttr(kNameSpaceID_None, nsGkAtoms::autoplay) &&
|
||||
mAutoplayEnabled) {
|
||||
if (CanActivateAutoplay()) {
|
||||
mPaused = PR_FALSE;
|
||||
// We changed mPaused which can affect AddRemoveSelfReference
|
||||
AddRemoveSelfReference();
|
||||
|
||||
if (mDecoder) {
|
||||
SetPlayedOrSeeked(PR_TRUE);
|
||||
mDecoder->Play();
|
||||
|
@ -1685,7 +1799,7 @@ PRBool nsHTMLMediaElement::IsPotentiallyPlaying() const
|
|||
// TODO:
|
||||
// playback has not stopped due to errors,
|
||||
// and the element has not paused for user interaction
|
||||
return
|
||||
return
|
||||
!mPaused &&
|
||||
(mReadyState == nsIDOMHTMLMediaElement::HAVE_ENOUGH_DATA ||
|
||||
mReadyState == nsIDOMHTMLMediaElement::HAVE_FUTURE_DATA) &&
|
||||
|
@ -1714,38 +1828,61 @@ void nsHTMLMediaElement::UpdateMediaSize(nsIntSize size)
|
|||
mMediaSize = size;
|
||||
}
|
||||
|
||||
void nsHTMLMediaElement::DestroyContent()
|
||||
void nsHTMLMediaElement::NotifyOwnerDocumentActivityChanged()
|
||||
{
|
||||
if (mDecoder) {
|
||||
mDecoder->Shutdown();
|
||||
mDecoder = nsnull;
|
||||
nsIDocument* ownerDoc = GetOwnerDoc();
|
||||
// Don't pause if we have no ownerDoc. Something native must have created
|
||||
// us and be expecting us to work without a document.
|
||||
PRBool pauseForInactiveDocument =
|
||||
ownerDoc && (!ownerDoc->IsActive() || !ownerDoc->IsVisible());
|
||||
|
||||
if (pauseForInactiveDocument != mPausedForInactiveDocument) {
|
||||
mPausedForInactiveDocument = pauseForInactiveDocument;
|
||||
if (mDecoder) {
|
||||
if (pauseForInactiveDocument) {
|
||||
mDecoder->Pause();
|
||||
mDecoder->Suspend();
|
||||
} else {
|
||||
mDecoder->Resume();
|
||||
if (IsPotentiallyPlaying()) {
|
||||
mDecoder->Play();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mChannel) {
|
||||
mChannel->Cancel(NS_BINDING_ABORTED);
|
||||
mChannel = nsnull;
|
||||
}
|
||||
nsGenericHTMLElement::DestroyContent();
|
||||
|
||||
AddRemoveSelfReference();
|
||||
}
|
||||
|
||||
void nsHTMLMediaElement::Freeze()
|
||||
void nsHTMLMediaElement::AddRemoveSelfReference()
|
||||
{
|
||||
mPausedBeforeFreeze = mPaused;
|
||||
if (!mPaused) {
|
||||
Pause();
|
||||
}
|
||||
if (mDecoder) {
|
||||
mDecoder->Suspend();
|
||||
}
|
||||
}
|
||||
// XXX we could release earlier here in many situations if we examined
|
||||
// which event listeners are attached. Right now we assume there is a
|
||||
// potential listener for every event. We would also have to keep the
|
||||
// element alive if it was playing and producing audio output --- right now
|
||||
// that's covered by the !mPaused check.
|
||||
nsIDocument* ownerDoc = GetOwnerDoc();
|
||||
|
||||
void nsHTMLMediaElement::Thaw()
|
||||
{
|
||||
if (!mPausedBeforeFreeze) {
|
||||
Play();
|
||||
}
|
||||
// See the comment at the top of this file for the explanation of this
|
||||
// boolean expression.
|
||||
PRBool needSelfReference = (!ownerDoc || ownerDoc->IsActive()) &&
|
||||
(mDelayingLoadEvent ||
|
||||
(!mPaused && mDecoder && !mDecoder->IsEnded()) ||
|
||||
(mDecoder && mDecoder->IsSeeking()) ||
|
||||
CanActivateAutoplay() ||
|
||||
mNetworkState == nsIDOMHTMLMediaElement::NETWORK_LOADING);
|
||||
|
||||
if (mDecoder) {
|
||||
mDecoder->Resume();
|
||||
if (needSelfReference != mHasSelfReference) {
|
||||
mHasSelfReference = needSelfReference;
|
||||
if (needSelfReference) {
|
||||
NS_ADDREF(this);
|
||||
} else {
|
||||
// Dispatch Release asynchronously so that we don't destroy this object
|
||||
// inside a call stack of method calls on this object
|
||||
nsCOMPtr<nsIRunnable> event =
|
||||
NS_NEW_RUNNABLE_METHOD(nsHTMLMediaElement, this, DoRelease);
|
||||
NS_DispatchToMainThread(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1848,6 +1985,9 @@ void nsHTMLMediaElement::ChangeDelayLoadStatus(PRBool aDelay) {
|
|||
mLoadBlockedDoc->UnblockOnload(PR_FALSE);
|
||||
mLoadBlockedDoc = nsnull;
|
||||
}
|
||||
|
||||
// We changed mDelayingLoadEvent which can affect AddRemoveSelfReference
|
||||
AddRemoveSelfReference();
|
||||
}
|
||||
|
||||
already_AddRefed<nsILoadGroup> nsHTMLMediaElement::GetDocumentLoadGroup()
|
||||
|
|
|
@ -1945,3 +1945,36 @@ nsHTMLOptionCollection::GetSelect(nsIDOMHTMLSelectElement **aReturn)
|
|||
NS_IF_ADDREF(*aReturn = mSelect);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLOptionCollection::Add(nsIDOMHTMLOptionElement *aOption,
|
||||
PRInt32 aIndex, PRUint8 optional_argc)
|
||||
{
|
||||
if (!aOption) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (aIndex < -1) {
|
||||
return NS_ERROR_DOM_INDEX_SIZE_ERR;
|
||||
}
|
||||
|
||||
if (!mSelect) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
PRUint32 length;
|
||||
GetLength(&length);
|
||||
|
||||
if (optional_argc == 0 || aIndex == -1 || aIndex > (PRInt32)length) {
|
||||
// IE appends in these cases
|
||||
aIndex = length;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMNode> beforeNode;
|
||||
Item(aIndex, getter_AddRefs(beforeNode));
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLOptionElement> beforeElement =
|
||||
do_QueryInterface(beforeNode);
|
||||
|
||||
return mSelect->Add(aOption, beforeElement);
|
||||
}
|
||||
|
|
|
@ -75,6 +75,9 @@ function cleanupFiles() {
|
|||
);
|
||||
}
|
||||
|
||||
is(singleFileInput.files.length, 0, "single-file .files.length"); // bug 524421
|
||||
is(multiFileInput.files.length, 0, "multi-file .files.length"); // bug 524421
|
||||
|
||||
setFileInputs();
|
||||
|
||||
is(singleFileInput.multiple, false, "single-file input .multiple");
|
||||
|
@ -113,6 +116,10 @@ iframe.onload = function() {
|
|||
}
|
||||
|
||||
cleanupFiles();
|
||||
|
||||
is(singleFileInput.files.length, 0, "single-file .files.length"); // bug 524421
|
||||
is(multiFileInput.files.length, 0, "multi-file .files.length"); // bug 524421
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
|
|
|
@ -88,7 +88,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=369370
|
|||
|
||||
kidWin.close();
|
||||
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
|
||||
prefs.clearUserPref("browser.enable_automatic_image_resizing");
|
||||
try {
|
||||
prefs.clearUserPref("browser.enable_automatic_image_resizing");
|
||||
} catch (ex) {
|
||||
// throws if it wasn't already set because app default was true
|
||||
}
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче