Merge mozilla-central to tracemonkey.

This commit is contained in:
Robert Sayre 2009-10-29 08:48:15 -07:00
Родитель bb172578ff c888c1980e
Коммит 67efa6c0c3
272 изменённых файлов: 4440 добавлений и 2417 удалений

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

@ -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

66
config/mozunit.py Normal file
Просмотреть файл

@ -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())

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

@ -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();
}

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