This commit is contained in:
Richard Newman 2012-04-29 23:41:26 -07:00
Родитель 8b54c4dcbe 3fa80ac988
Коммит 712d9846fa
225 изменённых файлов: 3826 добавлений и 20077 удалений

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

@ -237,7 +237,7 @@ AndroidPresenter.prototype.actionInvoked = function(aObject, aActionName) {
gecko: {
type: 'Accessibility:Event',
eventType: ANDROID_TYPE_VIEW_CLICKED,
text: [UtteranceGenerator.genForAction(aObject, aActionName)]
text: UtteranceGenerator.genForAction(aObject, aActionName)
}
});
};

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

@ -54,7 +54,7 @@ var UtteranceGenerator = {
},
genForAction: function(aObject, aActionName) {
return gStringBundle.GetStringFromName(this.gActionMap[aActionName]);
return [gStringBundle.GetStringFromName(this.gActionMap[aActionName])];
},
verbosityRoleMap: {

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

@ -71,10 +71,13 @@ nsXULTreeAccessible::
mFlags |= eXULTreeAccessible;
mTree = nsCoreUtils::GetTreeBoxObject(aContent);
if (mTree)
mTree->GetView(getter_AddRefs(mTreeView));
NS_ASSERTION(mTree, "Can't get mTree!\n");
NS_ASSERTION(mTree && mTreeView, "Can't get mTree or mTreeView!\n");
if (mTree) {
nsCOMPtr<nsITreeView> treeView;
mTree->GetView(getter_AddRefs(treeView));
mTreeView = treeView;
}
nsIContent* parentContent = mContent->GetParent();
if (parentContent) {
@ -95,14 +98,12 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(nsXULTreeAccessible)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsXULTreeAccessible,
nsAccessible)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mTree)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mTreeView)
CycleCollectorTraverseCache(tmp->mAccessibleCache, &cb);
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsXULTreeAccessible,
nsAccessible)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mTree)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mTreeView)
ClearCache(tmp->mAccessibleCache);
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
@ -145,10 +146,11 @@ nsXULTreeAccessible::NativeState()
void
nsXULTreeAccessible::Value(nsString& aValue)
{
// Return the value is the first selected child.
aValue.Truncate();
if (!mTreeView)
return;
// Return the value is the first selected child.
nsCOMPtr<nsITreeSelection> selection;
mTreeView->GetSelection(getter_AddRefs(selection));
if (!selection)
@ -739,13 +741,11 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(nsXULTreeItemAccessibleBase)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsXULTreeItemAccessibleBase,
nsAccessible)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mTree)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mTreeView)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsXULTreeItemAccessibleBase,
nsAccessible)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mTree)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mTreeView)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(nsXULTreeItemAccessibleBase)

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

@ -143,7 +143,7 @@ protected:
virtual already_AddRefed<nsAccessible> CreateTreeItemAccessible(PRInt32 aRow);
nsCOMPtr<nsITreeBoxObject> mTree;
nsCOMPtr<nsITreeView> mTreeView;
nsITreeView* mTreeView;
nsAccessibleHashtable mAccessibleCache;
};
@ -244,7 +244,7 @@ protected:
void GetCellName(nsITreeColumn* aColumn, nsAString& aName);
nsCOMPtr<nsITreeBoxObject> mTree;
nsCOMPtr<nsITreeView> mTreeView;
nsITreeView* mTreeView;
PRInt32 mRow;
};

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

@ -818,14 +818,12 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(nsXULTreeGridCellAccessible)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsXULTreeGridCellAccessible,
nsLeafAccessible)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mTree)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mTreeView)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mColumn)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsXULTreeGridCellAccessible,
nsLeafAccessible)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mTree)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mTreeView)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mColumn)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END

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

@ -210,7 +210,7 @@ protected:
enum { eAction_Click = 0 };
nsCOMPtr<nsITreeBoxObject> mTree;
nsCOMPtr<nsITreeView> mTreeView;
nsITreeView* mTreeView;
PRInt32 mRow;
nsCOMPtr<nsITreeColumn> mColumn;

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

@ -408,6 +408,8 @@
@BINPATH@/components/messageWakeupService.manifest
@BINPATH@/components/SettingsManager.js
@BINPATH@/components/SettingsManager.manifest
@BINPATH@/components/SettingsService.js
@BINPATH@/components/SettingsService.manifest
@BINPATH@/components/nsFilePicker.js
@BINPATH@/components/nsFilePicker.manifest
#ifdef MOZ_B2G_RIL

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

@ -62,6 +62,10 @@ DEFINES += \
-DAPP_VERSION="$(MOZ_APP_VERSION)" \
-DFIREFOX_ICO=\"$(DIST)/branding/firefox.ico\" \
-DDOCUMENT_ICO=\"$(DIST)/branding/document.ico\" \
-DNEWWINDOW_ICO=\"$(DIST)/branding/newwindow.ico\" \
-DNEWTAB_ICO=\"$(DIST)/branding/newtab.ico\" \
-DPBMODE_ICO=\"$(DIST)/branding/pbmode.ico\" \
$(NULL)
ifdef LIBXUL_SDK #{

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

@ -1,10 +1,14 @@
<?xml version="1.0"?>
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1333739604000">
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1335396801000">
<emItems>
<emItem blockID="i58" id="webmaster@buzzzzvideos.info">
<versionRange minVersion="0" maxVersion="*">
</versionRange>
</emItem>
<emItem blockID="i86" id="{45147e67-4020-47e2-8f7a-55464fb535aa}">
<versionRange minVersion="0" maxVersion="*">
</versionRange>
</emItem>
<emItem blockID="i41" id="{99079a25-328f-4bd4-be04-00955acaa0a7}">
<versionRange minVersion="0.1" maxVersion="4.3.1.00" severity="1">
</versionRange>
@ -81,6 +85,10 @@
<versionRange minVersion="2.0.3" maxVersion="2.0.3">
</versionRange>
</emItem>
<emItem blockID="i83" id="flash@adobee.com">
<versionRange minVersion="0" maxVersion="*">
</versionRange>
</emItem>
<emItem blockID="i59" id="ghostviewer@youtube2.com">
<versionRange minVersion="0" maxVersion="*">
</versionRange>
@ -99,6 +107,10 @@
</emItem>
<emItem blockID="i7" id="{2224e955-00e9-4613-a844-ce69fccaae91}">
</emItem>
<emItem blockID="i84" id="pink@rosaplugin.info">
<versionRange minVersion="0" maxVersion="*">
</versionRange>
</emItem>
<emItem blockID="i67" id="youtube2@youtube2.com">
<versionRange minVersion="0" maxVersion="*">
</versionRange>
@ -161,6 +173,10 @@
<versionRange minVersion="2.2" maxVersion="2.2">
</versionRange>
</emItem>
<emItem blockID="i82" id="{8f42fb8b-b6f6-45de-81c0-d6d39f54f971}">
<versionRange minVersion="0" maxVersion="*">
</versionRange>
</emItem>
<emItem blockID="i19" id="{46551EC9-40F0-4e47-8E18-8E5CF550CFB8}">
<versionRange minVersion="1.1b1" maxVersion="1.1b1">
</versionRange>
@ -196,6 +212,9 @@
<pluginItem blockID="p80">
<match name="description" exp="[^\d\._]((0(\.\d+(\.\d+([_\.]\d+)?)?)?)|(1\.(([0-5](\.\d+([_\.]\d+)?)?)|(6(\.0([_\.](0?\d|1\d|2\d|30))?)?)|(7(\.0([_\.][0-2])?)?))))([^\d\._]|$)" /> <match name="filename" exp="(npjp2\.dll)|(libnpjp2\.so)" /> <versionRange severity="1"></versionRange>
</pluginItem>
<pluginItem blockID="p85">
<match name="filename" exp="JavaPlugin2_NPAPI\.plugin" /> <versionRange minVersion="0" maxVersion="12.9.0" severity="1"></versionRange>
</pluginItem>
</pluginItems>
<gfxItems>

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

@ -45,6 +45,9 @@
IDI_APPICON ICON FIREFOX_ICO
IDI_DOCUMENT ICON DOCUMENT_ICO
IDI_APPLICATION ICON FIREFOX_ICO
IDI_NEWWINDOW ICON NEWWINDOW_ICO
IDI_NEWTAB ICON NEWTAB_ICO
IDI_PBMODE ICON PBMODE_ICO
STRINGTABLE DISCARDABLE
BEGIN

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

@ -32,7 +32,7 @@ function runAltLeftClickTest() {
}
function runShiftLeftClickTest() {
let listener = new WindowListener("chrome://browser/content/browser.xul", function(aWindow) {
let listener = new WindowListener(getBrowserURL(), function(aWindow) {
Services.wm.removeListener(listener);
addPageShowListener(aWindow.gBrowser, function() {
info("URL should be loaded in a new window");

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

@ -58,6 +58,9 @@ WINDOWS_BRANDING_FILES = \
wizHeader.bmp \
wizHeaderRTL.bmp \
wizWatermark.bmp \
newwindow.ico \
newtab.ico \
pbmode.ico \
$(NULL)
OSX_BRANDING_FILES = \

Двоичные данные
browser/branding/aurora/newtab.ico Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.1 KiB

Двоичные данные
browser/branding/aurora/newwindow.ico Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.1 KiB

Двоичные данные
browser/branding/aurora/pbmode.ico Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.1 KiB

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

@ -58,6 +58,9 @@ WINDOWS_BRANDING_FILES = \
wizHeader.bmp \
wizHeaderRTL.bmp \
wizWatermark.bmp \
newwindow.ico \
newtab.ico \
pbmode.ico \
$(NULL)
OSX_BRANDING_FILES = \

Двоичные данные
browser/branding/nightly/newtab.ico Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.1 KiB

Двоичные данные
browser/branding/nightly/newwindow.ico Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.1 KiB

Двоичные данные
browser/branding/nightly/pbmode.ico Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.1 KiB

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

@ -58,6 +58,9 @@ WINDOWS_BRANDING_FILES = \
wizHeader.bmp \
wizHeaderRTL.bmp \
wizWatermark.bmp \
newwindow.ico \
newtab.ico \
pbmode.ico \
$(NULL)
OSX_BRANDING_FILES = \

Двоичные данные
browser/branding/official/newtab.ico Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.1 KiB

Двоичные данные
browser/branding/official/newwindow.ico Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.1 KiB

Двоичные данные
browser/branding/official/pbmode.ico Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.1 KiB

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

@ -58,6 +58,9 @@ WINDOWS_BRANDING_FILES = \
wizHeader.bmp \
wizHeaderRTL.bmp \
wizWatermark.bmp \
newwindow.ico \
newtab.ico \
pbmode.ico \
$(NULL)
OSX_BRANDING_FILES = \

Двоичные данные
browser/branding/unofficial/newtab.ico Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.1 KiB

Двоичные данные
browser/branding/unofficial/newwindow.ico Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.1 KiB

Двоичные данные
browser/branding/unofficial/pbmode.ico Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.1 KiB

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

@ -49,6 +49,7 @@ richlistitem[type="download"]:not([selected]) button {
.downloadCancelMenuItem,
.download-state:not(:-moz-any([state="1"], /* Finished */
[state="2"], /* Failed */
[state="3"], /* Canceled */
[state="6"], /* Blocked (parental) */
[state="8"], /* Blocked (dirty) */

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

@ -56,18 +56,19 @@ const DownloadsPanel = {
//// Initialization and termination
/**
* State of the downloads panel, based on one of the kPanel constants.
* Internal state of the downloads panel, based on one of the kState
* constants. This is not the same state as the XUL panel element.
*/
_panelState: 0,
_state: 0,
/** Download data has not been loaded. */
get kPanelUninitialized() 0,
/** Download data is loading, but the user interface is invisible. */
get kPanelHidden() 1,
/** The panel is not linked to downloads data yet. */
get kStateUninitialized() 0,
/** This object is linked to data, but the panel is invisible. */
get kStateHidden() 1,
/** The panel will be shown as soon as possible. */
get kPanelShowing() 2,
/** The panel is open, though download data might still be loading. */
get kPanelShown() 3,
get kStateShowing() 2,
/** The panel is open. */
get kStateShown() 3,
/**
* Location of the panel overlay.
@ -84,12 +85,12 @@ const DownloadsPanel = {
*/
initialize: function DP_initialize(aCallback)
{
if (this._panelState != this.kPanelUninitialized) {
if (this._state != this.kStateUninitialized) {
DownloadsOverlayLoader.ensureOverlayLoaded(this.kDownloadsOverlay,
aCallback);
return;
}
this._panelState = this.kPanelHidden;
this._state = this.kStateHidden;
window.addEventListener("unload", this.onWindowUnload, false);
@ -115,7 +116,7 @@ const DownloadsPanel = {
*/
terminate: function DP_terminate()
{
if (this._panelState == this.kPanelUninitialized) {
if (this._state == this.kStateUninitialized) {
return;
}
@ -127,7 +128,7 @@ const DownloadsPanel = {
DownloadsViewController.terminate();
DownloadsCommon.data.removeView(DownloadsView);
this._panelState = this.kPanelUninitialized;
this._state = this.kStateUninitialized;
},
//////////////////////////////////////////////////////////////////////////////
@ -163,7 +164,7 @@ const DownloadsPanel = {
setTimeout(function () DownloadsPanel._openPopupIfDataReady(), 0);
}.bind(this));
this._panelState = this.kPanelShowing;
this._state = this.kStateShowing;
},
/**
@ -181,7 +182,7 @@ const DownloadsPanel = {
// Ensure that we allow the panel to be reopened. Note that, if the popup
// was open, then the onPopupHidden event handler has already updated the
// current state, otherwise we must update the state ourselves.
this._panelState = this.kPanelHidden;
this._state = this.kStateHidden;
},
/**
@ -189,8 +190,8 @@ const DownloadsPanel = {
*/
get isPanelShowing()
{
return this._panelState == this.kPanelShowing ||
this._panelState == this.kPanelShown;
return this._state == this.kStateShowing ||
this._state == this.kStateShown;
},
//////////////////////////////////////////////////////////////////////////////
@ -220,6 +221,8 @@ const DownloadsPanel = {
return;
}
this._state = this.kStateShown;
// Since at most one popup is open at any given time, we can set globally.
DownloadsCommon.indicatorData.attentionSuppressed = true;
@ -246,7 +249,7 @@ const DownloadsPanel = {
DownloadsButton.releaseAnchor();
// Allow the panel to be reopened.
this._panelState = this.kPanelHidden;
this._state = this.kStateHidden;
},
//////////////////////////////////////////////////////////////////////////////
@ -275,7 +278,7 @@ const DownloadsPanel = {
_focusPanel: function DP_focusPanel()
{
// We may be invoked while the panel is still waiting to be shown.
if (this._panelState != this.kPanelShown) {
if (this._state != this.kStateShown) {
return;
}
@ -295,12 +298,10 @@ const DownloadsPanel = {
{
// We don't want to open the popup if we already displayed it, or if we are
// still loading data.
if (this._panelState != this.kPanelShowing || DownloadsView.loading) {
if (this._state != this.kStateShowing || DownloadsView.loading) {
return;
}
this._panelState = this.kPanelShown;
// Make sure that clicking outside the popup cannot reopen it accidentally.
this.panel.popupBoxObject.setConsumeRollupEvent(Ci.nsIPopupBoxObject
.ROLLUP_CONSUME);
@ -308,6 +309,16 @@ const DownloadsPanel = {
// Ensure the anchor is visible. If that is not possible, show the panel
// anchored to the top area of the window, near the default anchor position.
DownloadsButton.getAnchor(function DP_OPIDR_callback(aAnchor) {
// At this point, if the window is minimized, opening the panel could fail
// without any notification, and there would be no way to either open or
// close the panel anymore. To prevent this, check if the window is
// minimized and in that case force the panel to the closed state.
if (window.windowState == Ci.nsIDOMChromeWindow.STATE_MINIMIZED) {
DownloadsButton.releaseAnchor();
this._state = this.kStateHidden;
return;
}
if (aAnchor) {
this.panel.openPopup(aAnchor, "bottomcenter topright", 0, 0, false,
null);

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

@ -394,11 +394,6 @@ const DownloadsData = {
//////////////////////////////////////////////////////////////////////////////
//// Persistent data loading
/**
* Asynchronous database statement used to read the list of downloads.
*/
_statement: null,
/**
* Represents an executing statement, allowing its cancellation.
*/
@ -455,10 +450,19 @@ const DownloadsData = {
}
} else {
if (this._loadState != this.kLoadAll) {
// Reload the list from the database asynchronously.
this._statement = Services.downloads.DBConnection.createAsyncStatement(
"SELECT * FROM moz_downloads ORDER BY id DESC");
this._pendingStatement = this._statement.executeAsync(this);
// Load only the relevant columns from the downloads database. The
// columns are read in the init_FromDataRow method of DownloadsDataItem.
let statement = Services.downloads.DBConnection.createAsyncStatement(
"SELECT id, target, name, source, referrer, state, "
+ "startTime, endTime, currBytes, maxBytes "
+ "FROM moz_downloads "
+ "ORDER BY id DESC"
);
try {
this._pendingStatement = statement.executeAsync(this);
} finally {
statement.finalize();
}
}
}
},
@ -472,10 +476,6 @@ const DownloadsData = {
this._pendingStatement.cancel();
this._pendingStatement = null;
}
if (this._statement) {
this._statement.finalize();
this._statement = null;
}
// Close all the views on the current data. Create a copy of the array
// because some views might unregister while processing this event.

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

@ -78,6 +78,11 @@ DownloadsUI.prototype = {
// Show the panel in the most recent browser window, if present.
let browserWin = gBrowserGlue.getMostRecentBrowserWindow();
if (browserWin) {
// The most recent browser window could have been minimized, in that case
// it must be restored to allow the panel to open properly.
if (browserWin.windowState == Ci.nsIDOMChromeWindow.STATE_MINIMIZED) {
browserWin.restore();
}
browserWin.focus();
browserWin.DownloadsPanel.showPanel();
return;

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

@ -1366,7 +1366,7 @@ FeedWriter.prototype = {
}
var faviconURI = makeURI(readerURI.prePath + "/favicon.ico");
var self = this;
this._faviconService.setAndLoadFaviconForPage(readerURI, faviconURI, false,
this._faviconService.setAndFetchFaviconForPage(readerURI, faviconURI, false,
function (aURI, aDataLen, aData, aMimeType) {
if (aDataLen > 0) {
var dataURL = "data:" + aMimeType + ";base64," +

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

@ -448,9 +448,8 @@ WebContentConverterRegistrar.prototype = {
// Now Ask the user and provide the proper callback
message = this._getFormattedString("addProtocolHandler",
[aTitle, uri.host, aProtocol]);
var fis = Cc["@mozilla.org/browser/favicon-service;1"].
getService(Ci.nsIFaviconService);
var notificationIcon = fis.getFaviconLinkForIcon(uri);
var notificationIcon = uri.prePath + "/favicon.ico";
var notificationValue = "Protocol Registration: " + aProtocol;
var addButton = {
label: this._getString("addProtocolHandlerAddButton"),

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

@ -8,6 +8,7 @@
let bg = Cc["@mozilla.org/browser/browserglue;1"].getService(Ci.nsIObserver);
let gOriginalMigrationVersion;
const BROWSER_URL = getBrowserURL();
let localStore = {
get RDF() Cc["@mozilla.org/rdf/rdf-service;1"].getService(Ci.nsIRDFService),
@ -16,10 +17,10 @@ let localStore = {
get toolbar()
{
delete this.toolbar;
let toolbar = this.RDF.GetResource("chrome://browser/content/browser.xul#PersonalToolbar");
let toolbar = this.RDF.GetResource(BROWSER_URL + "#PersonalToolbar");
// Add the entry to the persisted set for this document if it's not there.
// See nsXULDocument::Persist.
let doc = this.RDF.GetResource("chrome://browser/content/browser.xul");
let doc = this.RDF.GetResource(BROWSER_URL);
let persist = this.RDF.GetResource("http://home.netscape.com/NC-rdf#persist");
if (!this.store.HasAssertion(doc, persist, toolbar, true)) {
this.store.Assert(doc, persist, toolbar, true);

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

@ -133,6 +133,10 @@ PrivateBrowsingService.prototype = {
// Whether private browsing has been turned on from the command line
_lastChangedByCommandLine: false,
// Telemetry measurements
_enterTimestamps: {},
_exitTimestamps: {},
// XPCOM registration
classID: Components.ID("{c31f4883-839b-45f6-82ad-a6a9bc5ad599}"),
@ -308,6 +312,7 @@ PrivateBrowsingService.prototype = {
// restore has been completed
this._currentStatus = STATE_IDLE;
this._obs.notifyObservers(null, "private-browsing-transition-complete", "");
this._recordTransitionTime("completed");
break;
case STATE_WAITING_FOR_RESTORE:
// too soon to notify...
@ -323,6 +328,51 @@ PrivateBrowsingService.prototype = {
}
},
_recordTransitionTime: function PBS__recordTransitionTime(aPhase) {
// To record the time spent in private browsing transitions, note that we
// cannot use the TelemetryStopwatch module, because it reports its results
// immediately when the timer is stopped. In this case, we need to delay
// the actual histogram update after we are out of private browsing mode.
if (this._inPrivateBrowsing) {
this._enterTimestamps[aPhase] = Date.now();
} else {
if (this._quitting) {
// If we are quitting the browser, we don't care collecting the data,
// because we wouldn't be able to record it with telemetry.
return;
}
this._exitTimestamps[aPhase] = Date.now();
if (aPhase == "completed") {
// After we finished exiting the private browsing mode, we can finally
// record the telemetry data, for the enter and the exit processes.
this._reportTelemetry();
}
}
},
_reportTelemetry: function PBS__reportTelemetry() {
function reportTelemetryEntry(aHistogramId, aValue) {
try {
Services.telemetry.getHistogramById(aHistogramId).add(aValue);
} catch (ex) {
Cu.reportError(ex);
}
}
reportTelemetryEntry(
"PRIVATE_BROWSING_TRANSITION_ENTER_PREPARATION_MS",
this._enterTimestamps.prepared - this._enterTimestamps.started);
reportTelemetryEntry(
"PRIVATE_BROWSING_TRANSITION_ENTER_TOTAL_MS",
this._enterTimestamps.completed - this._enterTimestamps.started);
reportTelemetryEntry(
"PRIVATE_BROWSING_TRANSITION_EXIT_PREPARATION_MS",
this._exitTimestamps.prepared - this._exitTimestamps.started);
reportTelemetryEntry(
"PRIVATE_BROWSING_TRANSITION_EXIT_TOTAL_MS",
this._exitTimestamps.completed - this._exitTimestamps.started);
},
_canEnterPrivateBrowsingMode: function PBS__canEnterPrivateBrowsingMode() {
let cancelEnter = Cc["@mozilla.org/supports-PRBool;1"].
createInstance(Ci.nsISupportsPRBool);
@ -537,6 +587,8 @@ PrivateBrowsingService.prototype = {
this._autoStarted = this._prefs.getBoolPref("browser.privatebrowsing.autostart");
this._inPrivateBrowsing = val != false;
this._recordTransitionTime("started");
let data = val ? "enter" : "exit";
let quitting = Cc["@mozilla.org/supports-PRBool;1"].
@ -551,6 +603,8 @@ PrivateBrowsingService.prototype = {
this._obs.notifyObservers(quitting, "private-browsing", data);
this._recordTransitionTime("prepared");
// load the appropriate session
this._onAfterPrivateBrowsingModeChange();
} catch (ex) {

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

@ -37,7 +37,7 @@
function test() {
// We need to open a new window for this so that its docshell would get destroyed
// when clearing the PB mode flag.
let newWin = window.openDialog("chrome://browser/content/", "_blank", "chrome,all,dialog=no");
let newWin = window.openDialog(getBrowserURL(), "_blank", "chrome,all,dialog=no");
waitForExplicitFinish();
SimpleTest.waitForFocus(function() {
let notificationCount = 0;

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

@ -0,0 +1,42 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyServiceGetter(this, "gPrivateBrowsing",
PRIVATEBROWSING_CONTRACT_ID,
"nsIPrivateBrowsingService");
function waitForTransition(aEnabled, aCallback) {
Services.obs.addObserver(function PBT_transition(aSubject, aTopic, aData) {
Services.obs.removeObserver(PBT_transition, aTopic, false);
// Telemetry data is recorded just after the private browsing transition
// observers are notified, thus we must wait for this observer to return.
do_execute_soon(aCallback);
}, "private-browsing-transition-complete", false);
gPrivateBrowsing.privateBrowsingEnabled = aEnabled;
}
function checkHistogram(aId) {
// Check that we have data either in the first bucket (that doesn't
// count towards the sum) or one of the other buckets, by checking
// the sum of the values.
let snapshot = Services.telemetry.getHistogramById(aId).snapshot();
do_check_true(snapshot.sum > 0 || snapshot.counts[0] > 0);
}
function do_test() {
do_test_pending();
waitForTransition(true, function PBT_enabled() {
waitForTransition(false, function PBT_disabled() {
checkHistogram("PRIVATE_BROWSING_TRANSITION_ENTER_PREPARATION_MS");
checkHistogram("PRIVATE_BROWSING_TRANSITION_ENTER_TOTAL_MS");
checkHistogram("PRIVATE_BROWSING_TRANSITION_EXIT_PREPARATION_MS");
checkHistogram("PRIVATE_BROWSING_TRANSITION_EXIT_TOTAL_MS");
do_test_finished();
});
});
}

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

@ -0,0 +1,44 @@
/* ***** 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
* Ehsan Akhgari.
* Portions created by the Initial Developer are Copyright (C) 2008
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Ehsan Akhgari <ehsan.akhgari@gmail.com> (Original Author)
*
* 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 ***** */
// Checks that telemetry data for private browsing transitions is recorded.
function run_test() {
PRIVATEBROWSING_CONTRACT_ID = "@mozilla.org/privatebrowsing;1";
load("do_test_privatebrowsing_telemetry.js");
do_test();
}

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

@ -0,0 +1,44 @@
/* ***** 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
* Ehsan Akhgari.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Ehsan Akhgari <ehsan.akhgari@gmail.com> (Original Author)
*
* 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 ***** */
// Checks that telemetry data for private browsing transitions is recorded.
function run_test() {
PRIVATEBROWSING_CONTRACT_ID = "@mozilla.org/privatebrowsing-wrapper;1";
load("do_test_privatebrowsing_telemetry.js");
do_test();
}

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

@ -12,12 +12,14 @@ tail = tail_privatebrowsing.js
[test_privatebrowsing_autostart.js]
[test_privatebrowsing_commandline.js]
[test_privatebrowsing_exit.js]
[test_privatebrowsing_telemetry.js]
[test_privatebrowsingwrapper_autostart.js]
[test_privatebrowsingwrapper_commandline.js]
[test_privatebrowsingwrapper_exit.js]
[test_privatebrowsingwrapper_placesTitleNoUpdate.js]
[test_privatebrowsingwrapper_removeDataFromDomain.js]
[test_privatebrowsingwrapper_removeDataFromDomain_activeDownloads.js]
[test_privatebrowsingwrapper_telemetry.js]
[test_removeDataFromDomain.js]
[test_removeDataFromDomain_activeDownloads.js]
[test_transition_nooffline.js]

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

@ -73,12 +73,15 @@ function test() {
let uniqueValue = "unik" + Date.now();
let uniqueText = "pi != " + Math.random();
// Be consistent: let the page actually display, as we are "interacting" with it.
Services.prefs.setBoolPref("general.warnOnAboutConfig", false);
// make sure that the next closed window will increase getClosedWindowCount
let max_windows_undo = gPrefService.getIntPref("browser.sessionstore.max_windows_undo");
gPrefService.setIntPref("browser.sessionstore.max_windows_undo", max_windows_undo + 1);
let max_windows_undo = Services.prefs.getIntPref("browser.sessionstore.max_windows_undo");
Services.prefs.setIntPref("browser.sessionstore.max_windows_undo", max_windows_undo + 1);
let closedWindowCount = ss.getClosedWindowCount();
provideWindow(function (newWin) {
provideWindow(function onTestURLLoaded(newWin) {
newWin.gBrowser.addTab().linkedBrowser.stop();
// mark the window with some unique data to be restored later on
@ -105,28 +108,31 @@ function test() {
// SSTabRestored will fire more than once, so we need to make sure we count them
let restoredTabs = 0;
let expectedTabs = data.tabs.length;
whenWindowLoaded(newWin2, function () {
newWin2.gBrowser.tabContainer.addEventListener("SSTabRestored", function(aEvent) {
if (++restoredTabs < expectedTabs)
return;
newWin2.gBrowser.tabContainer.removeEventListener("SSTabRestored", arguments.callee, true);
newWin2.addEventListener("SSTabRestored", function sstabrestoredListener(aEvent) {
++restoredTabs;
info("Restored tab " + restoredTabs + "/" + expectedTabs);
if (restoredTabs < expectedTabs) {
return;
}
is(newWin2.gBrowser.tabs.length, 2,
"The window correctly restored 2 tabs");
is(newWin2.gBrowser.currentURI.spec, testURL,
"The window correctly restored the URL");
newWin2.removeEventListener("SSTabRestored", sstabrestoredListener, true);
let textbox = newWin2.content.document.getElementById("textbox");
is(textbox.value, uniqueText,
"The window correctly restored the form");
is(ss.getWindowValue(newWin2, uniqueKey), uniqueValue,
"The window correctly restored the data associated with it");
is(newWin2.gBrowser.tabs.length, 2,
"The window correctly restored 2 tabs");
is(newWin2.gBrowser.currentURI.spec, testURL,
"The window correctly restored the URL");
// clean up
newWin2.close();
gPrefService.clearUserPref("browser.sessionstore.max_windows_undo");
finish();
}, true);
});
let textbox = newWin2.content.document.getElementById("textbox");
is(textbox.value, uniqueText,
"The window correctly restored the form");
is(ss.getWindowValue(newWin2, uniqueKey), uniqueValue,
"The window correctly restored the data associated with it");
// clean up
newWin2.close();
Services.prefs.clearUserPref("browser.sessionstore.max_windows_undo");
Services.prefs.clearUserPref("general.warnOnAboutConfig");
finish();
}, true);
}, testURL);
}

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

@ -40,10 +40,8 @@
// Tests that code completion works properly.
const TEST_URI = "chrome://browser/content/browser.xul";
function test() {
addTab(TEST_URI);
addTab(getBrowserURL());
browser.addEventListener("DOMContentLoaded", testChrome, false);
}

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

@ -637,6 +637,7 @@ bin/components/@DLL_PREFIX@nkgnomevfs@DLL_SUFFIX@
@BINPATH@/webapprt/chrome/webapprt@JAREXT@
@BINPATH@/webapprt/chrome/webapprt.manifest
@BINPATH@/webapprt/components/CommandLineHandler.js
@BINPATH@/webapprt/components/ContentPolicy.js
@BINPATH@/webapprt/components/DirectoryProvider.js
@BINPATH@/webapprt/components/components.manifest
@BINPATH@/webapprt/defaults/preferences/prefs.js

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

@ -27,6 +27,9 @@ const PREF_NEWTAB_ENABLED = "browser.newtabpage.enabled";
// The maximum number of results we want to retrieve from history.
const HISTORY_RESULTS_LIMIT = 100;
// The gather telemetry topic.
const TOPIC_GATHER_TELEMETRY = "gather-telemetry";
/**
* Singleton that provides storage functionality.
*/
@ -585,6 +588,47 @@ let Links = {
Ci.nsISupportsWeakReference])
};
/**
* Singleton used to collect telemetry data.
*
*/
let Telemetry = {
/**
* Initializes object.
*/
init: function Telemetry_init() {
Services.obs.addObserver(this, TOPIC_GATHER_TELEMETRY, false);
},
/**
* Collects data.
*/
_collect: function Telemetry_collect() {
let probes = [
{ histogram: "NEWTAB_PAGE_ENABLED",
value: AllPages.enabled },
{ histogram: "NEWTAB_PAGE_PINNED_SITES_COUNT",
value: PinnedLinks.links.length },
{ histogram: "NEWTAB_PAGE_BLOCKED_SITES_COUNT",
value: Object.keys(BlockedLinks.links).length }
];
probes.forEach(function Telemetry_collect_forEach(aProbe) {
Services.telemetry.getHistogramById(aProbe.histogram)
.add(aProbe.value);
});
},
/**
* Listens for gather telemetry topic.
*/
observe: function Telemetry_observe(aSubject, aTopic, aData) {
this._collect();
}
};
Telemetry.init();
/**
* Singleton that provides the public API of this JSM.
*/

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

@ -141,7 +141,7 @@ var tasksCfg = [
get title() _getString("taskbar.tasks.newTab.label"),
get description() _getString("taskbar.tasks.newTab.description"),
args: "-new-tab about:blank",
iconIndex: 0, // Fx app icon
iconIndex: 3, // New window icon
open: true,
close: true, // The jump list already has an app launch icon, but
// we don't always update the list on shutdown.
@ -153,7 +153,7 @@ var tasksCfg = [
get title() _getString("taskbar.tasks.newWindow.label"),
get description() _getString("taskbar.tasks.newWindow.description"),
args: "-browser",
iconIndex: 0, // Fx app icon
iconIndex: 2, // New tab icon
open: true,
close: true, // No point, but we don't always update the list on
// shutdown. Thus true for consistency.
@ -174,7 +174,7 @@ var tasksCfg = [
return _getString("taskbar.tasks.enterPrivacyMode.description");
},
args: "-private-toggle",
iconIndex: 0, // Fx app icon
iconIndex: 4, // Private browsing mode icon
get open() {
// Don't show when inside permanent private browsing mode
return !_privateBrowsingSvc.autoStarted;

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

@ -0,0 +1,232 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.
import automationutils
import os
import re
import socket
import shutil
import sys
import tempfile
import time
from automation import Automation
from devicemanager import DeviceManager, NetworkTools
class B2GRemoteAutomation(Automation):
_devicemanager = None
def __init__(self, deviceManager, appName='', remoteLog=None,
marionette=None):
self._devicemanager = deviceManager
self._appName = appName
self._remoteProfile = None
self._remoteLog = remoteLog
self.marionette = marionette
# Default our product to b2g
self._product = "b2g"
Automation.__init__(self)
def setDeviceManager(self, deviceManager):
self._devicemanager = deviceManager
def setAppName(self, appName):
self._appName = appName
def setRemoteProfile(self, remoteProfile):
self._remoteProfile = remoteProfile
def setProduct(self, product):
self._product = product
def setRemoteLog(self, logfile):
self._remoteLog = logfile
# Set up what we need for the remote environment
def environment(self, env=None, xrePath=None, crashreporter=True):
# Because we are running remote, we don't want to mimic the local env
# so no copying of os.environ
if env is None:
env = {}
return env
def checkForCrashes(self, directory, symbolsPath):
# XXX: This will have to be updated after crash reporting on b2g
# is in place.
dumpDir = tempfile.mkdtemp()
self._devicemanager.getDirectory(self._remoteProfile + '/minidumps/', dumpDir)
automationutils.checkForCrashes(dumpDir, symbolsPath, self.lastTestSeen)
try:
shutil.rmtree(dumpDir)
except:
print "WARNING: unable to remove directory: %s" % (dumpDir)
def buildCommandLine(self, app, debuggerInfo, profileDir, testURL, extraArgs):
# if remote profile is specified, use that instead
if (self._remoteProfile):
profileDir = self._remoteProfile
cmd, args = Automation.buildCommandLine(self, app, debuggerInfo, profileDir, testURL, extraArgs)
return app, args
def getLanIp(self):
nettools = NetworkTools()
return nettools.getLanIp()
def waitForFinish(self, proc, utilityPath, timeout, maxTime, startTime,
debuggerInfo, symbolsPath, logger):
""" Wait for mochitest to finish (as evidenced by a signature string
in logcat), or for a given amount of time to elapse with no
output.
"""
timeout = timeout or 120
didTimeout = False
done = time.time() + timeout
while True:
currentlog = proc.stdout
if currentlog:
done = time.time() + timeout
print currentlog
if 'INFO SimpleTest FINISHED' in currentlog:
return 0
else:
if time.time() > done:
self.log.info("TEST-UNEXPECTED-FAIL | %s | application timed "
"out after %d seconds with no output",
self.lastTestSeen, int(timeout))
return 1
def getDeviceStatus(self, serial=None):
# Get the current status of the device. If we know the device
# serial number, we look for that, otherwise we use the (presumably
# only) device shown in 'adb devices'.
serial = serial or self._devicemanager.deviceSerial
status = 'unknown'
for line in self._devicemanager.runCmd(['devices']).stdout.readlines():
result = re.match('(.*?)\t(.*)', line)
if result:
thisSerial = result.group(1)
if not serial or thisSerial == serial:
serial = thisSerial
status = result.group(2)
return (serial, status)
def rebootDevice(self):
# find device's current status and serial number
serial, status = self.getDeviceStatus()
# reboot!
self._devicemanager.checkCmd(['reboot'])
# wait for device to come back to previous status
print 'waiting for device to come back online after reboot'
start = time.time()
rserial, rstatus = self.getDeviceStatus(serial)
while rstatus != 'device':
if time.time() - start > 120:
# device hasn't come back online in 2 minutes, something's wrong
raise Exception("Device %s (status: %s) not back online after reboot" % (serial, rstatus))
time.sleep(5)
rserial, rstatus = self.getDeviceStatus(serial)
print 'device:', serial, 'status:', rstatus
def Process(self, cmd, stdout=None, stderr=None, env=None, cwd=None):
# On a desktop or fennec run, the Process method invokes a gecko
# process in which to run mochitests. For B2G, we simply
# reboot the device (which was configured with a test profile
# already), wait for B2G to start up, and then navigate to the
# test url using Marionette. There doesn't seem to be any way
# to pass env variables into the B2G process, but this doesn't
# seem to matter.
instance = self.B2GInstance(self._devicemanager)
# reboot device so it starts up with the mochitest profile
# XXX: We could potentially use 'stop b2g' + 'start b2g' to achieve
# a similar effect; will see which is more stable while attempting
# to bring up the continuous integration.
self.rebootDevice()
# Infrequently, gecko comes up before networking does, so wait a little
# bit to give the network time to become available.
# XXX: need a more robust mechanism for this
time.sleep(20)
# Set up port forwarding again for Marionette, since any that
# existed previously got wiped out by the reboot.
self._devicemanager.checkCmd(['forward',
'tcp:%s' % self.marionette.port,
'tcp:%s' % self.marionette.port])
# start a marionette session
session = self.marionette.start_session()
if 'b2g' not in session:
raise Exception("bad session value %s returned by start_session" % session)
# start the tests by navigating to the mochitest url
self.marionette.execute_script("window.location.href='%s';" % self.testURL)
return instance
# be careful here as this inner class doesn't have access to outer class members
class B2GInstance(object):
"""Represents a B2G instance running on a device, and exposes
some process-like methods/properties that are expected by the
automation.
"""
def __init__(self, dm):
self.dm = dm
self.lastloglines = []
@property
def pid(self):
# a dummy value to make the automation happy
return 0
@property
def stdout(self):
# Return any part of logcat output that wasn't returned
# previously. This is done by fetching about the last 50
# lines of the log (logcat -t 50 generally fetches 50-58 lines),
# and comparing against the previous set to find new lines.
t = self.dm.runCmd(['logcat', '-t', '50']).stdout.read()
if t == None: return ''
t = t.strip('\n').strip()
loglines = t.split('\n')
line_index = 0
# If there are more than 50 lines, we skip the first 20; this
# is because the number of lines returned
# by logcat -t 50 varies (usually between 50 and 58).
log_index = 20 if len(loglines) > 50 else 0
for index, line in enumerate(loglines[log_index:]):
line_index = index + log_index + 1
try:
self.lastloglines.index(line)
except ValueError:
break
newoutput = '\n'.join(loglines[line_index:])
self.lastloglines = loglines
return newoutput
def wait(self, timeout = None):
# this should never happen
raise Exception("'wait' called on B2GInstance")
def kill(self):
# this should never happen
raise Exception("'kill' called on B2GInstance")

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

@ -137,7 +137,7 @@ public class DoCommand {
String ffxProvider = "org.mozilla.ffxcp";
String fenProvider = "org.mozilla.fencp";
private final String prgVersion = "SUTAgentAndroid Version 1.07";
private final String prgVersion = "SUTAgentAndroid Version 1.08";
public enum Command
{

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

@ -5,14 +5,14 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=246699
-->
<head>
<title>Test for Bug 246699</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=246699">Mozilla Bug 246699</a>
<p id="display"></p>
<div id="content" style="display: none">
<iframe id="load-frame"></iframe>
<iframe id="load-frame"></iframe>
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
@ -21,9 +21,14 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=246699
** Test for Bug 246699
** (should produce stack information for caps errors)
**/
function isError(e)
{
return e.constructor.name === "Error" || e.constructor.name === "TypeError";
}
function hasStack(e)
{
return e.constructor.name === "Error" && /inciteCaps/.test(e.stack);
return isError(e) && /inciteCaps/.test(e.stack);
}
function inciteCaps(f)

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

@ -119,6 +119,7 @@ MOZ_ENABLE_PROFILER_SPS = @MOZ_ENABLE_PROFILER_SPS@
MOZ_JPROF = @MOZ_JPROF@
MOZ_SHARK = @MOZ_SHARK@
MOZ_CALLGRIND = @MOZ_CALLGRIND@
MOZ_VALGRIND = @MOZ_VALGRIND@
MOZ_VTUNE = @MOZ_VTUNE@
MOZ_ETW = @MOZ_ETW@
MOZ_TRACE_JSCALLS = @MOZ_TRACE_JSCALLS@

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

@ -50,8 +50,5 @@ endif
AUTO_DEPS +=$(GENERATED_DIRS_DEPS)
# Complain loudly if deps have not loaded so getargv != $(NULL)
ifndef getargv
$(error config/makefiles/makeutil.mk has not been included)
endif
$(call requiredfunction,getargv)

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

@ -5,13 +5,6 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.
# Usage: $(call banner,foo bar tans)
banner =\
$(info )\
$(info ***************************************************************************)\
$(info ** BANNER: $(1) $(2) $(3) $(4) $(5) $(6) $(7) $(8) $(9))\
$(info ***************************************************************************)\
## Identify function argument types
istype =$(if $(value ${1}),list,scalar)
isval =$(if $(filter-out list,$(call istype,${1})),true)
@ -35,6 +28,62 @@ argv +=)
## getarglist() would be a more accurate name but is longer to type
getargv = $(if $(call isvar,$(1)),$($(1)),$(argv))
###########################################################################
# Strip [n] leading options from an argument list. This will allow passing
# extra args to user functions that will not propogate to sub-$(call )'s
# Usage: $(call subargv,2)
subargv =$(wordlist $(1),$(words $(getargv)),$(getargv))
###########################################################################
# Intent: Display a distinct banner heading in the output stream
# Usage: $(call banner,BUILDING: foo bar tans)
# Debug:
# target-preqs = \
# $(call banner,target-preqs-BEGIN) \
# foo bar tans \
# $(call banner,target-preqs-END) \
# $(NULL)
# target: $(target-preqs)
banner =\
$(info )\
$(info ***************************************************************************)\
$(info ** $(getargv))\
$(info ***************************************************************************)\
$(NULL)
#####################################################################
# Intent: Determine if a string or pattern is contained in a list
# Usage: strcmp - $(call if_XinY,clean,$(MAKECMDGOALS))
# : pattern - $(call if_XinY,clean%,$(MAKECMDGOALS))
is_XinY =$(filter $(1),$(call subargv,3,$(getargv)))
#####################################################################
# Provide an alternate var to support testing
ifdef MAKEUTILS_UNIT_TEST
mcg_goals=TEST_MAKECMDGOALS
else
mcg_goals=MAKECMDGOALS
endif
# Intent: Conditionals for detecting common/tier target use
# Todo: are check, install, test needed ?
isTargetStem = $(sort $(foreach pat, $(1)% %$(1), $(call is_XinY,$(pat),${$(mcg_goals)})))
isTargetStemClean = $(call isTargetStem,clean)
isTargetStemExport = $(call isTargetStem,export)
isTargetStemLibs = $(call isTargetStem,libs)
isTargetStemTools = $(call isTargetStem,tools)
##################################################
# Intent: Validation functions / unit test helpers
errorifneq =$(if $(subst $(strip $(1)),$(NULL),$(strip $(2))),$(error expected [$(1)] but found [$(2)]))
# Intent: verify function declaration exists
requiredfunction =$(foreach func,$(1) $(2) $(3) $(4) $(5) $(6) $(7) $(8) $(9),$(if $(value $(func)),$(NULL),$(error required function [$(func)] is unavailable)))
## http://www.gnu.org/software/make/manual/make.html#Call-Function
## Usage: o = $(call map,origin,o map $(MAKE))
map = $(foreach val,$(2),$(call $(1),$(val)))

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

@ -10,6 +10,8 @@ srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MAKEUTILS_UNIT_TEST = 1
include $(topsrcdir)/config/makefiles/makeutils.mk
##------------------_##
@ -29,9 +31,10 @@ all::
check::
@true
###########################################################################
## Logic processed at compile time so be selective about when to test
ifneq ($(NULL),$(findstring check,$(MAKECMDGOALS))) #{
## Verify istype, isval, isvar, getargv, subargv
ifneq ($(NULL),$(findstring check,$(MAKECMDGOALS))) #
ifdef VERBOSE
@ -45,11 +48,14 @@ $(info Running test: istype, getargv)
$(info ===========================================================================)
endif
## Silent errors are oh so much fun
ifndef istype
$(error makeutils.mk was not included)
ifndef requiredfunction
$(error requiredfunction is not defined)
endif
include $(topsrcdir)/config/makefiles/test/check_XinY.mk
$(call requiredfunc,istype isvar isval)
# arg_scalar = [scalar|literal]
arg_list = foo bar
arg_ref = arg_list
@ -124,4 +130,13 @@ ifdef MANUAL_TEST #{
$(error TEST FAILED: processing should not reach this point)
endif #}
endif #} check in MAKECMDGOALS
# Verify subargv expansion
##########################
subargs=foo bar tans fans
subargs_exp=tans fans
subargs_found=$(call subargv,4,$(subargs))
ifneq ($(subargs_exp),$(subargs_found))
$(error subargv(4,$(subargs)): expected [$(subargs_exp)] found [$(subargs_found)])
endif
endif #} unit_test: istype, isvar, isval, getargv, subargv

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

@ -0,0 +1,47 @@
# -*- makefile -*-
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.
# Verify dependencies are available
$(call requiredfunction,getargv subargv is_XinY errorifneq)
#############################
ifdef VERBOSE
$(warning )
$(call banner,Unit test: is_XinY)
endif
zero := 0
one := 1
# Verify 'invalid' is not matched
val := invalid
$(call errorifneq,$(zero),$(words $(call is_XinY,foo,$(val))))
$(call errorifneq,$(zero),$(words $(call is_XinY,clean,$(val))))
$(call errorifneq,$(zero),$(words $(call is_XinY,clean%,$(val))))
# verify strcmp('clean')
val := clean
$(call errorifneq,$(zero),$(words $(call is_XinY,foo,$(val))))
$(call errorifneq,$(one),$(words $(call is_XinY,clean,$(val))))
$(call errorifneq,$(one,$(words $(call is_XinY,clean%,$(val)))))
$(call errorifneq,$(one),$(words $(call is_XinY,%clean,$(val))))
# List match for 'clean'
val := blah clean distclean FcleanG clean-level-1
wanted := clean distclean clean-level-1
$(call errorifneq,$(zero),$(words $(call is_XinY_debug,foo,$(val))))
$(call errorifneq,$(one),$(words $(call is_XinY,clean,$(val))))
$(call errorifneq,$(one),$(words $(call is_XinY,distclean,$(val))))
# pattern match 'clean'
# match: clean, distclean, clean-level-1
# exclude: FcleanG
TEST_MAKECMDGOALS := $(val)
$(call errorifneq,3,$(words $(call isTargetStemClean)))
TEST_MAKECMDGOALS := invalid
$(call errorifneq,$(zero),$(words $(call isTargetStemClean)))

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

@ -4609,15 +4609,7 @@ MOZ_USE_NATIVE_POPUP_WINDOWS=
MOZ_ANDROID_HISTORY=
MOZ_WEBSMS_BACKEND=
MOZ_GRAPHITE=1
case "${target}" in
*darwin*)
ACCESSIBILITY=
;;
*)
ACCESSIBILITY=1
;;
esac
ACCESSIBILITY=1
case "$target_os" in
mingw*)
@ -5550,10 +5542,9 @@ AC_DEFINE(IBMBIDI)
dnl ========================================================
dnl accessibility support on by default on all platforms
dnl except OS X.
dnl ========================================================
MOZ_ARG_DISABLE_BOOL(accessibility,
[ --disable-accessibility Disable accessibility support (off by default on OS X)],
[ --disable-accessibility Disable accessibility support],
ACCESSIBILITY=,
ACCESSIBILITY=1 )
if test "$ACCESSIBILITY"; then
@ -5835,14 +5826,10 @@ dnl = Check alsa availability on Linux if using sydneyaudio
dnl ========================================================
dnl If using sydneyaudio with Linux, ensure that the alsa library is available
if test -n "$MOZ_SYDNEYAUDIO"; then
case "$target_os" in
linux*)
PKG_CHECK_MODULES(MOZ_ALSA, alsa, ,
if test -n "$MOZ_SYDNEYAUDIO" -a "$OS_TARGET" = "Linux"; then
PKG_CHECK_MODULES(MOZ_ALSA, alsa, ,
[echo "$MOZ_ALSA_PKG_ERRORS"
AC_MSG_ERROR([Need alsa for Ogg, Wave or WebM decoding on Linux. Disable with --disable-ogg --disable-wave --disable-webm. (On Ubuntu, you might try installing the package libasound2-dev.)])])
;;
esac
fi
dnl ========================================================

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

@ -402,7 +402,7 @@ public:
/**
* Return this node as an Element. Should only be used for nodes
* for which IsElement() is true.
* for which IsElement() is true. This is defined inline in Element.h.
*/
mozilla::dom::Element* AsElement();
@ -755,9 +755,9 @@ public:
* Get the parent nsINode for this node if it is an Element.
* @return the parent node
*/
nsINode* GetElementParent() const
mozilla::dom::Element* GetElementParent() const
{
return mParent && mParent->IsElement() ? mParent : nsnull;
return mParent && mParent->IsElement() ? mParent->AsElement() : nsnull;
}
/**

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

@ -362,12 +362,6 @@ nsCCUncollectableMarker::Observe(nsISupports* aSubject, const char* aTopic,
}
}
if (cleanupJS) {
nsContentUtils::UnmarkGrayJSListenersInCCGenerationDocuments(sGeneration);
MarkMessageManagers();
xpc_UnmarkSkippableJSHolders();
}
#ifdef MOZ_XUL
nsXULPrototypeCache* xulCache = nsXULPrototypeCache::GetInstance();
if (xulCache) {
@ -375,6 +369,18 @@ nsCCUncollectableMarker::Observe(nsISupports* aSubject, const char* aTopic,
}
#endif
static bool previousWasJSCleanup = false;
if (cleanupJS) {
nsContentUtils::UnmarkGrayJSListenersInCCGenerationDocuments(sGeneration);
MarkMessageManagers();
previousWasJSCleanup = true;
} else if (previousWasJSCleanup) {
previousWasJSCleanup = false;
if (!prepareForCC) {
xpc_UnmarkSkippableJSHolders();
}
}
return NS_OK;
}

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

@ -132,7 +132,7 @@ public:
// Called by the video decoder object, on the main thread,
// when it has read the metadata containing video dimensions,
// etc.
void MetadataLoaded(PRUint32 aChannels, PRUint32 aRate);
void MetadataLoaded(PRUint32 aChannels, PRUint32 aRate, bool aHasAudio);
// Called by the video decoder object, on the main thread,
// when it has read the first frame of the video
@ -794,6 +794,9 @@ protected:
// The CORS mode when loading the media element
mozilla::CORSMode mCORSMode;
// True if the media has an audio track
bool mHasAudio;
};
#endif

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

@ -177,7 +177,7 @@ nsHTMLAudioElement::MozSetup(PRUint32 aChannels, PRUint32 aRate)
return rv;
}
MetadataLoaded(aChannels, aRate);
MetadataLoaded(aChannels, aRate, true);
mAudioStream->SetVolume(mVolume);
return NS_OK;
}

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

@ -1459,7 +1459,8 @@ nsHTMLMediaElement::nsHTMLMediaElement(already_AddRefed<nsINodeInfo> aNodeInfo)
mShuttingDown(false),
mLoadIsSuspended(false),
mMediaSecurityVerified(false),
mCORSMode(CORS_NONE)
mCORSMode(CORS_NONE),
mHasAudio(false)
{
#ifdef PR_LOGGING
if (!gMediaElementLog) {
@ -2258,10 +2259,11 @@ void nsHTMLMediaElement::ProcessMediaFragmentURI()
}
}
void nsHTMLMediaElement::MetadataLoaded(PRUint32 aChannels, PRUint32 aRate)
void nsHTMLMediaElement::MetadataLoaded(PRUint32 aChannels, PRUint32 aRate, bool aHasAudio)
{
mChannels = aChannels;
mRate = aRate;
mHasAudio = aHasAudio;
ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_METADATA);
DispatchAsyncEvent(NS_LITERAL_STRING("durationchange"));
DispatchAsyncEvent(NS_LITERAL_STRING("loadedmetadata"));

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

@ -219,3 +219,11 @@ NS_IMETHODIMP nsHTMLVideoElement::GetMozFrameDelay(double *aMozFrameDelay) {
*aMozFrameDelay = container ? container->GetFrameDelay() : 0;
return NS_OK;
}
/* readonly attribute bool mozHasAudio */
NS_IMETHODIMP nsHTMLVideoElement::GetMozHasAudio(bool *aHasAudio) {
NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
*aHasAudio = mHasAudio;
return NS_OK;
}

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

@ -72,6 +72,7 @@ class nsHTMLDocument : public nsDocument,
{
public:
using nsDocument::SetDocumentURI;
using nsDocument::GetPlugins;
nsHTMLDocument();
virtual nsresult Init();

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

@ -408,7 +408,8 @@ void nsBuiltinDecoder::AudioAvailable(float* aFrameBuffer,
}
void nsBuiltinDecoder::MetadataLoaded(PRUint32 aChannels,
PRUint32 aRate)
PRUint32 aRate,
bool aHasAudio)
{
NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
if (mShuttingDown) {
@ -435,7 +436,7 @@ void nsBuiltinDecoder::MetadataLoaded(PRUint32 aChannels,
// Make sure the element and the frame (if any) are told about
// our new size.
Invalidate();
mElement->MetadataLoaded(aChannels, aRate);
mElement->MetadataLoaded(aChannels, aRate, aHasAudio);
}
if (!mResourceLoaded) {

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

@ -555,7 +555,8 @@ public:
// Called when the metadata from the media file has been read.
// Call on the main thread only.
void MetadataLoaded(PRUint32 aChannels,
PRUint32 aRate);
PRUint32 aRate,
bool aHasAudio);
// Called when the first frame has been loaded.
// Call on the main thread only.

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

@ -152,21 +152,23 @@ private:
nsCOMPtr<nsBuiltinDecoder> mDecoder;
public:
nsAudioMetadataEventRunner(nsBuiltinDecoder* aDecoder, PRUint32 aChannels,
PRUint32 aRate) :
PRUint32 aRate, bool aHasAudio) :
mDecoder(aDecoder),
mChannels(aChannels),
mRate(aRate)
mRate(aRate),
mHasAudio(aHasAudio)
{
}
NS_IMETHOD Run()
{
mDecoder->MetadataLoaded(mChannels, mRate);
mDecoder->MetadataLoaded(mChannels, mRate, mHasAudio);
return NS_OK;
}
const PRUint32 mChannels;
const PRUint32 mRate;
const bool mHasAudio;
};
// Owns the global state machine thread and counts of
@ -1515,7 +1517,7 @@ nsresult nsBuiltinDecoderStateMachine::DecodeMetadata()
mDecoder->RequestFrameBufferLength(frameBufferLength);
}
nsCOMPtr<nsIRunnable> metadataLoadedEvent =
new nsAudioMetadataEventRunner(mDecoder, mInfo.mAudioChannels, mInfo.mAudioRate);
new nsAudioMetadataEventRunner(mDecoder, mInfo.mAudioChannels, mInfo.mAudioRate, HasAudio());
NS_DispatchToMainThread(metadataLoadedEvent, NS_DISPATCH_NORMAL);
if (mState == DECODER_STATE_DECODING_METADATA) {

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

@ -156,6 +156,7 @@ _TEST_FILES = \
test_video_to_canvas.html \
use_large_cache.js \
test_audiowrite.html \
test_mozHasAudio.html \
$(NULL)
# Don't run in suite

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

@ -47,6 +47,15 @@ var gPausedAfterEndedTests = gSmallTests.concat([
{ name:"small-shot.ogg", type:"video/ogg", duration:0.276 }
]);
// Test the mozHasAudio property
var gMozHasAudioTests = [
{ name:"big.wav", type:"audio/x-wav", duration:9.278981, size:102444, hasAudio:undefined },
{ name:"320x240.ogv", type:"video/ogg", width:320, height:240, duration:0.233, size:28942, hasAudio:false },
{ name:"short-video.ogv", type:"video/ogg", duration:1.081, hasAudio:true },
{ name:"seek.webm", type:"video/webm", duration:3.966, size:215529, hasAudio:false },
{ name:"bogus.duh", type:"bogus/duh" }
];
// These are files that we want to make sure we can play through. We can
// also check metadata. Put files of the same type together in this list so if
// something crashes we have some idea of which backend is responsible.

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

@ -0,0 +1,41 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test playback of media files that should play OK</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<script type="text/javascript" src="manifest.js"></script>
</head>
<body>
<pre id="test">
<script class="testbody" type="text/javascript">
var manager = new MediaTestManager;
function onloadedmetadata(e) {
var t = e.target;
is(t.mozHasAudio, t.hasAudio, "The element reports the wrong audio property." + t.token);
manager.finished(t.token);
}
function startTest(test, token) {
var elemType = /^audio/.test(test.type) ? "audio" : "video";
var element = document.createElement(elemType);
element.token = token;
manager.started(token);
element.src = test.name;
element.name = test.name;
element.hasAudio = test.hasAudio;
element.addEventListener("loadedmetadata", onloadedmetadata, false);
element.load();
}
manager.runTests(gMozHasAudioTests, startTest);
</script>
</pre>
</body>
</html>

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

@ -3896,6 +3896,10 @@ nsDocShell::LoadURI(const PRUnichar * aURI,
rv = LoadURI(uri, loadInfo, extraFlags, true);
// Save URI string in case it's needed later when
// sending to search engine service in EndPageLoad()
mOriginalUriString = uriString;
return rv;
}
@ -6355,27 +6359,33 @@ nsDocShell::EndPageLoad(nsIWebProgress * aProgress,
if (keywordsEnabled && (kNotFound == dotLoc)) {
// only send non-qualified hosts to the keyword server
//
// If this string was passed through nsStandardURL by
// chance, then it may have been converted from UTF-8 to
// ACE, which would result in a completely bogus keyword
// query. Here we try to recover the original Unicode
// value, but this is not 100% correct since the value may
// have been normalized per the IDN normalization rules.
//
// Since we don't have access to the exact original string
// that was entered by the user, this will just have to do.
bool isACE;
nsCAutoString utf8Host;
nsCOMPtr<nsIIDNService> idnSrv =
do_GetService(NS_IDNSERVICE_CONTRACTID);
if (idnSrv &&
NS_SUCCEEDED(idnSrv->IsACE(host, &isACE)) && isACE &&
NS_SUCCEEDED(idnSrv->ConvertACEtoUTF8(host, utf8Host)))
sURIFixup->KeywordToURI(utf8Host,
if (!mOriginalUriString.IsEmpty()) {
sURIFixup->KeywordToURI(mOriginalUriString,
getter_AddRefs(newURI));
else
sURIFixup->KeywordToURI(host, getter_AddRefs(newURI));
}
else {
//
// If this string was passed through nsStandardURL by
// chance, then it may have been converted from UTF-8 to
// ACE, which would result in a completely bogus keyword
// query. Here we try to recover the original Unicode
// value, but this is not 100% correct since the value may
// have been normalized per the IDN normalization rules.
//
// Since we don't have access to the exact original string
// that was entered by the user, this will just have to do.
bool isACE;
nsCAutoString utf8Host;
nsCOMPtr<nsIIDNService> idnSrv =
do_GetService(NS_IDNSERVICE_CONTRACTID);
if (idnSrv &&
NS_SUCCEEDED(idnSrv->IsACE(host, &isACE)) && isACE &&
NS_SUCCEEDED(idnSrv->ConvertACEtoUTF8(host, utf8Host)))
sURIFixup->KeywordToURI(utf8Host,
getter_AddRefs(newURI));
else
sURIFixup->KeywordToURI(host, getter_AddRefs(newURI));
}
} // end keywordsEnabled
}
@ -8070,6 +8080,7 @@ nsDocShell::InternalLoad(nsIURI * aURI,
nsIRequest** aRequest)
{
nsresult rv = NS_OK;
mOriginalUriString.Truncate();
#ifdef PR_LOGGING
if (gDocShellLeakLog && PR_LOG_TEST(gDocShellLeakLog, PR_LOG_DEBUG)) {

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

@ -848,7 +848,8 @@ private:
nsCOMPtr<nsIAtom> mForcedCharset;
nsCOMPtr<nsIAtom> mParentCharset;
nsTObserverArray<nsWeakPtr> mPrivacyObservers;
PRInt32 mParentCharsetSource;
PRInt32 mParentCharsetSource;
nsCString mOriginalUriString;
#ifdef DEBUG
// We're counting the number of |nsDocShells| to help find leaks

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

@ -535,6 +535,8 @@ using mozilla::dom::indexedDB::IDBWrapperCache;
#include "DOMError.h"
#include "DOMRequest.h"
#include "mozilla/Likely.h"
#undef None // something included above defines this preprocessor symbol, maybe Xlib headers
#include "WebGLContext.h"
@ -1968,6 +1970,23 @@ WrapNativeParent(JSContext *cx, JSObject *scope, nsISupports *native,
return NS_OK;
}
// Helper to handle torn-down inner windows.
static inline nsresult
SetParentToWindow(nsGlobalWindow *win, JSObject **parent)
{
MOZ_ASSERT(win);
MOZ_ASSERT(win->IsInnerWindow());
*parent = win->FastGetGlobalJSObject();
if (MOZ_UNLIKELY(!*parent)) {
// The only known case where this can happen is when the inner window has
// been torn down. See bug 691178 comment 11.
MOZ_ASSERT(win->IsClosedOrClosing());
return NS_ERROR_FAILURE;
}
return NS_OK;
}
// static
nsISupports *
@ -4629,8 +4648,9 @@ nsDOMClassInfo::PreCreate(nsISupports *nativeObj, JSContext *cx,
}
if (piwin->IsOuterWindow()) {
*parentObj = ((nsGlobalWindow *)piwin.get())->
GetCurrentInnerWindowInternal()->GetGlobalJSObject();
nsGlobalWindow *win = ((nsGlobalWindow *)piwin.get())->
GetCurrentInnerWindowInternal();
return SetParentToWindow(win, parentObj);
}
return NS_OK;
@ -5165,20 +5185,15 @@ nsWindowSH::PreCreate(nsISupports *nativeObj, JSContext *cx,
nsGlobalWindow *win = nsGlobalWindow::FromSupports(nativeObj);
NS_ASSERTION(win->IsInnerWindow(), "Should be inner window.");
JSObject *winObj = win->FastGetGlobalJSObject();
if (!winObj) {
// We sometimes get a disconnected window during file api test. :-(
if (!win->GetOuterWindowInternal())
return NS_ERROR_FAILURE;
// See bug 691178 comment 11 for why this is necessary.
if (win->IsClosedOrClosing())
return NS_ERROR_FAILURE;
NS_ASSERTION(win->GetOuterWindowInternal()->IsCreatingInnerWindow(),
"should have a JS object by this point");
// If we're bootstrapping, we don't have a JS object yet.
if (win->GetOuterWindowInternal()->IsCreatingInnerWindow())
return NS_OK;
}
*parentObj = winObj;
return NS_OK;
return SetParentToWindow(win, parentObj);
}
// This JS class piggybacks on nsHTMLDocumentSH::ReleaseDocument()...
@ -6029,8 +6044,7 @@ nsDOMConstructor::PreCreate(JSContext *cx, JSObject *globalObj, JSObject **paren
}
nsGlobalWindow *win = static_cast<nsGlobalWindow *>(owner.get());
*parentObj = win->FastGetGlobalJSObject();
return NS_OK;
return SetParentToWindow(win, parentObj);
}
nsresult
@ -7480,7 +7494,7 @@ nsLocationSH::PreCreate(nsISupports *nativeObj, JSContext *cx,
}
*parentObj = sgo->GetGlobalJSObject();
return NS_OK;
return *parentObj ? NS_OK : NS_ERROR_FAILURE;
}
// DOM Navigator helper
@ -7579,14 +7593,7 @@ nsNavigatorSH::PreCreate(nsISupports *nativeObj, JSContext *cx,
return NS_ERROR_UNEXPECTED;
}
JSObject *global = win->GetGlobalJSObject();
if (global) {
*parentObj = global;
}
return NS_OK;
return SetParentToWindow(win, parentObj);
}
// DOM Node helper
@ -7853,7 +7860,7 @@ nsEventTargetSH::PreCreate(nsISupports *nativeObj, JSContext *cx,
*parentObj = native_parent ? native_parent->GetGlobalJSObject() : globalObj;
return NS_OK;
return *parentObj ? NS_OK : NS_ERROR_FAILURE;
}
NS_IMETHODIMP
@ -10005,9 +10012,8 @@ nsHistorySH::PreCreate(nsISupports *nativeObj, JSContext *cx,
NS_WARNING("refusing to create history object in the wrong scope");
return NS_ERROR_FAILURE;
}
*parentObj = static_cast<nsGlobalWindow *>(innerWindow.get())->FastGetGlobalJSObject();
return NS_OK;
return SetParentToWindow(static_cast<nsGlobalWindow *>(innerWindow.get()),
parentObj);
}
NS_IMETHODIMP

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

@ -95,6 +95,12 @@ public:
nsresult TimeStampToDOMOrFetchStart(mozilla::TimeStamp aStamp,
DOMTimeMilliSec* aResult);
inline DOMHighResTimeStamp TimeStampToDOMHighRes(mozilla::TimeStamp aStamp)
{
mozilla::TimeDuration duration = aStamp - mNavigationStartTimeStamp;
return duration.ToMilliseconds();
}
private:
nsDOMNavigationTiming(const nsDOMNavigationTiming &){};
~nsDOMNavigationTiming();

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

@ -319,3 +319,11 @@ nsPerformance::GetNavigation(nsIDOMPerformanceNavigation** aNavigation)
NS_IF_ADDREF(*aNavigation = mNavigation);
return NS_OK;
}
NS_IMETHODIMP
nsPerformance::Now(DOMHighResTimeStamp* aNow)
{
*aNow = mDOMTiming->TimeStampToDOMHighRes(mozilla::TimeStamp::Now());
return NS_OK;
}

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

@ -801,7 +801,8 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
properties should be a PropertyArrays instance.
"""
def __init__(self, descriptor, properties):
args = [Argument('JSContext*', 'aCx'), Argument('JSObject*', 'aGlobal')]
args = [Argument('JSContext*', 'aCx'), Argument('JSObject*', 'aGlobal'),
Argument('JSObject*', 'aReceiver')]
CGAbstractMethod.__init__(self, descriptor, 'CreateInterfaceObjects', 'JSObject*', args)
self.properties = properties
def definition_body(self):
@ -810,7 +811,7 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
getParentProto = "JS_GetObjectPrototype(aCx, aGlobal)"
else:
parentProtoName = self.descriptor.prototypeChain[-2]
getParentProto = "%s::GetProtoObject(aCx, aGlobal)" % (parentProtoName)
getParentProto = "%s::GetProtoObject(aCx, aGlobal, aReceiver)" % (parentProtoName)
needInterfaceObject = self.descriptor.interface.hasInterfaceObject()
needInterfacePrototypeObject = self.descriptor.interface.hasInterfacePrototypeObject()
@ -849,7 +850,7 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
" return NULL;\n"
"}") % getParentProto
call = CGGeneric(("return bindings::CreateInterfaceObjects(aCx, aGlobal, parentProto,\n"
call = CGGeneric(("return bindings::CreateInterfaceObjects(aCx, aGlobal, aReceiver, parentProto,\n"
" %s, %s,\n"
" %%(methods)s, %%(attrs)s, %%(consts)s, %%(staticMethods)s,\n"
" %s);") % (
@ -880,12 +881,20 @@ class CGGetPerInterfaceObject(CGAbstractMethod):
constructor object).
"""
def __init__(self, descriptor, name, idPrefix=""):
args = [Argument('JSContext*', 'aCx'), Argument('JSObject*', 'aGlobal')]
args = [Argument('JSContext*', 'aCx'), Argument('JSObject*', 'aGlobal'),
Argument('JSObject*', 'aReceiver')]
CGAbstractMethod.__init__(self, descriptor, name,
'JSObject*', args, inline=True)
self.id = idPrefix + "id::" + self.descriptor.name
def definition_body(self):
return """
/* aGlobal and aReceiver are usually the same, but they can be different
too. For example a sandbox often has an xray wrapper for a window as the
prototype of the sandbox's global. In that case aReceiver is the xray
wrapper and aGlobal is the sandbox's global.
*/
/* Make sure our global is sane. Hopefully we can remove this sometime */
if (!(js::GetObjectClass(aGlobal)->flags & JSCLASS_DOM_GLOBAL)) {
return NULL;
@ -894,7 +903,7 @@ class CGGetPerInterfaceObject(CGAbstractMethod):
JSObject** protoOrIfaceArray = GetProtoOrIfaceArray(aGlobal);
JSObject* cachedObject = protoOrIfaceArray[%s];
if (!cachedObject) {
protoOrIfaceArray[%s] = cachedObject = CreateInterfaceObjects(aCx, aGlobal);
protoOrIfaceArray[%s] = cachedObject = CreateInterfaceObjects(aCx, aGlobal, aReceiver);
}
/* cachedObject might _still_ be null, but that's OK */
@ -905,7 +914,6 @@ class CGGetProtoObjectMethod(CGGetPerInterfaceObject):
A method for getting the interface prototype object.
"""
def __init__(self, descriptor):
args = [Argument('JSContext*', 'aCx'), Argument('JSObject*', 'aGlobal')]
CGGetPerInterfaceObject.__init__(self, descriptor, "GetProtoObject")
def definition_body(self):
return """
@ -917,14 +925,13 @@ class CGGetConstructorObjectMethod(CGGetPerInterfaceObject):
A method for getting the interface constructor object.
"""
def __init__(self, descriptor):
args = [Argument('JSContext*', 'aCx'), Argument('JSObject*', 'aGlobal')]
CGGetPerInterfaceObject.__init__(self, descriptor, "GetConstructorObject", "constructors::")
def definition_body(self):
return """
/* Get the interface object for this class. This will create the object as
needed. */""" + CGGetPerInterfaceObject.definition_body(self)
def CheckPref(descriptor, scopeName, varName, retval, wrapperCache = None):
def CheckPref(descriptor, globalName, varName, retval, wrapperCache = None):
"""
Check whether bindings should be enabled for this descriptor. If not, set
varName to false and return retval.
@ -932,15 +939,23 @@ def CheckPref(descriptor, scopeName, varName, retval, wrapperCache = None):
if not descriptor.prefable:
return ""
if wrapperCache:
wrapperCache = "%s->ClearIsDOMBinding();\n" % (wrapperCache)
wrapperCache = " %s->ClearIsDOMBinding();\n" % (wrapperCache)
else:
wrapperCache = ""
return """
if (!%s->ExperimentalBindingsEnabled()) {
%s %s = false;
return %s;
{
XPCWrappedNativeScope* scope =
XPCWrappedNativeScope::FindInJSObjectScope(aCx, %s);
if (!scope) {
return %s;
}
if (!scope->ExperimentalBindingsEnabled()) {
%s %s = false;
return %s;
}
}
""" % (scopeName, wrapperCache, varName, retval)
""" % (globalName, retval, wrapperCache, varName, retval)
class CGDefineDOMInterfaceMethod(CGAbstractMethod):
"""
@ -948,7 +963,7 @@ class CGDefineDOMInterfaceMethod(CGAbstractMethod):
a given interface.
"""
def __init__(self, descriptor):
args = [Argument('JSContext*', 'aCx'), Argument('XPCWrappedNativeScope*', 'aScope'),
args = [Argument('JSContext*', 'aCx'), Argument('JSObject*', 'aReceiver'),
Argument('bool*', 'aEnabled')]
CGAbstractMethod.__init__(self, descriptor, 'DefineDOMInterface', 'bool', args)
@ -970,9 +985,11 @@ class CGDefineDOMInterfaceMethod(CGAbstractMethod):
else:
getter = "GetConstructorObject"
return CheckPref(self.descriptor, "aScope", "*aEnabled", "false") + """
return (" JSObject* global = JS_GetGlobalForObject(aCx, aReceiver);\n" +
CheckPref(self.descriptor, "global", "*aEnabled", "false") +
"""
*aEnabled = true;
return !!%s(aCx, aScope->GetGlobalJSObject());""" % (getter)
return !!%s(aCx, global, aReceiver);""" % (getter))
class CGNativeToSupportsMethod(CGAbstractStaticMethod):
"""
@ -1022,13 +1039,9 @@ class CGWrapMethod(CGAbstractMethod):
}
}
XPCWrappedNativeScope* scope =
XPCWrappedNativeScope::FindInJSObjectScope(aCx, parent);
if (!scope) {
return NULL;
}
JSObject* global = JS_GetGlobalForObject(aCx, parent);
%s
JSObject* proto = GetProtoObject(aCx, scope->GetGlobalJSObject());
JSObject* proto = GetProtoObject(aCx, global, global);
if (!proto) {
return NULL;
}
@ -1043,7 +1056,7 @@ class CGWrapMethod(CGAbstractMethod):
aObject->SetWrapper(obj);
return obj;""" % (CheckPref(self.descriptor, "scope", "*aTriedToWrap", "NULL", "aObject"))
return obj;""" % (CheckPref(self.descriptor, "global", "*aTriedToWrap", "NULL", "aObject"))
builtinNames = {
IDLType.Tags.bool: 'bool',

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

@ -25,7 +25,7 @@ DefineConstants(JSContext* cx, JSObject* obj, ConstantSpec* cs)
}
static JSObject*
CreateInterfaceObject(JSContext* cx, JSObject* global,
CreateInterfaceObject(JSContext* cx, JSObject* global, JSObject* receiver,
JSClass* constructorClass, JSObject* proto,
JSFunctionSpec* staticMethods, ConstantSpec* constants,
const char* name)
@ -54,7 +54,7 @@ CreateInterfaceObject(JSContext* cx, JSObject* global,
}
// This is Enumerable: False per spec.
if (!JS_DefineProperty(cx, global, name, OBJECT_TO_JSVAL(constructor), NULL,
if (!JS_DefineProperty(cx, receiver, name, OBJECT_TO_JSVAL(constructor), NULL,
NULL, 0)) {
return NULL;
}
@ -91,11 +91,11 @@ CreateInterfacePrototypeObject(JSContext* cx, JSObject* global,
}
JSObject*
CreateInterfaceObjects(JSContext *cx, JSObject *global, JSObject *parentProto,
JSClass *protoClass, JSClass *constructorClass,
JSFunctionSpec *methods, JSPropertySpec *properties,
ConstantSpec *constants, JSFunctionSpec *staticMethods,
const char* name)
CreateInterfaceObjects(JSContext* cx, JSObject* global, JSObject *receiver,
JSObject* protoProto, JSClass* protoClass,
JSClass* constructorClass, JSFunctionSpec* methods,
JSPropertySpec* properties, ConstantSpec* constants,
JSFunctionSpec* staticMethods, const char* name)
{
MOZ_ASSERT(protoClass || constructorClass, "Need at least one class!");
MOZ_ASSERT(!(methods || properties) || protoClass,
@ -107,7 +107,7 @@ CreateInterfaceObjects(JSContext *cx, JSObject *global, JSObject *parentProto,
JSObject* proto;
if (protoClass) {
proto = CreateInterfacePrototypeObject(cx, global, parentProto, protoClass,
proto = CreateInterfacePrototypeObject(cx, global, protoProto, protoClass,
methods, properties, constants);
if (!proto) {
return NULL;
@ -119,8 +119,8 @@ CreateInterfaceObjects(JSContext *cx, JSObject *global, JSObject *parentProto,
JSObject* interface;
if (constructorClass) {
interface = CreateInterfaceObject(cx, global, constructorClass, proto,
staticMethods, constants, name);
interface = CreateInterfaceObject(cx, global, receiver, constructorClass,
proto, staticMethods, constants, name);
if (!interface) {
return NULL;
}

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

@ -219,7 +219,11 @@ struct ConstantSpec
* Create a DOM interface object (if constructorClass is non-null) and/or a
* DOM interface prototype object (if protoClass is non-null).
*
* parentProto is the prototype to use for the interface prototype object.
* global is used as the parent of the interface object and the interface
* prototype object
* receiver is the object on which we need to define the interface object as a
* property
* protoProto is the prototype to use for the interface prototype object.
* protoClass is the JSClass to use for the interface prototype object.
* This is null if we should not create an interface prototype
* object.
@ -242,11 +246,11 @@ struct ConstantSpec
* returns the interface object.
*/
JSObject*
CreateInterfaceObjects(JSContext* cx, JSObject* global, JSObject* parentProto,
JSClass* protoClass, JSClass* constructorClass,
JSFunctionSpec* methods, JSPropertySpec* properties,
ConstantSpec* constants, JSFunctionSpec* staticMethods,
const char* name);
CreateInterfaceObjects(JSContext* cx, JSObject* global, JSObject* receiver,
JSObject* protoProto, JSClass* protoClass,
JSClass* constructorClass, JSFunctionSpec* methods,
JSPropertySpec* properties, ConstantSpec* constants,
JSFunctionSpec* staticMethods, const char* name);
template <class T>
inline bool

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

@ -47,6 +47,7 @@ class nsWrapperCache;
typedef unsigned long long DOMTimeStamp;
typedef unsigned long long DOMTimeMilliSec;
typedef double DOMHighResTimeStamp;
// Core
interface nsIDOMAttr;

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

@ -37,14 +37,16 @@
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
#include "domstubs.idl"
interface nsIDOMPerformanceTiming;
interface nsIDOMPerformanceNavigation;
[scriptable, uuid(446faf26-000b-4e66-a5fd-ae37c5ed6beb)]
[scriptable, uuid(ac274ec8-ee9f-44ef-b2f0-b13c22225a98)]
interface nsIDOMPerformance : nsISupports
{
readonly attribute nsIDOMPerformanceTiming timing;
readonly attribute nsIDOMPerformanceNavigation navigation;
DOMHighResTimeStamp now();
};

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

@ -48,7 +48,7 @@
* @status UNDER_DEVELOPMENT
*/
[scriptable, uuid(E3763903-928B-47C4-AC3B-C47EB43884CA)]
[scriptable, uuid(0a1c8b44-12a4-4316-b39f-feeee48475f8)]
interface nsIDOMHTMLVideoElement : nsIDOMHTMLMediaElement
{
attribute long width;
@ -75,5 +75,8 @@ interface nsIDOMHTMLVideoElement : nsIDOMHTMLMediaElement
// Time which the last painted video frame was late by, in seconds.
readonly attribute double mozFrameDelay;
// True if the video has an audio track available.
readonly attribute bool mozHasAudio;
};

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

@ -15,6 +15,7 @@ GRE_MODULE = 1
XPIDLSRCS = \
nsIDOMSettingsManager.idl \
nsISettingsService.idl \
$(NULL)
include $(topsrcdir)/config/rules.mk

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

@ -0,0 +1,27 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "domstubs.idl"
[scriptable, uuid(83d67430-8516-11e1-b0c4-0800200c9a66)]
interface nsISettingsServiceCallback : nsISupports
{
[implicit_jscontext]
void handle(in DOMString aName, in jsval aResult);
[implicit_jscontext]
void handleError(in DOMString aErrorMessage);
};
[scriptable, uuid(3ab3cbc0-8513-11e1-b0c4-0800200c9a66)]
interface nsISettingsServiceLock : nsISupports
{
void set(in string aName, in jsval aValue, in nsISettingsServiceCallback aCallback);
void get(in string aName, in nsISettingsServiceCallback aCallback);
};
[scriptable, uuid(3458e760-8513-11e1-b0c4-0800200c9a66)]
interface nsISettingsService : nsISupports
{
nsISettingsServiceLock getLock();
};

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

@ -1773,47 +1773,8 @@ bool nsPluginInstanceOwner::AddPluginView(const gfxRect& aRect)
return false;
}
JNIEnv* env = GetJNIForThread();
if (!env)
return false;
AndroidBridge::AutoLocalJNIFrame frame(env, 1);
jclass cls = env->FindClass("org/mozilla/gecko/GeckoAppShell");
#ifdef MOZ_JAVA_COMPOSITOR
nsAutoString metadata;
nsCOMPtr<nsIAndroidDrawMetadataProvider> metadataProvider =
AndroidBridge::Bridge()->GetDrawMetadataProvider();
metadataProvider->GetDrawMetadata(metadata);
jstring jMetadata = env->NewString(nsPromiseFlatString(metadata).get(), metadata.Length());
jmethodID method = env->GetStaticMethodID(cls,
"addPluginView",
"(Landroid/view/View;IIIILjava/lang/String;)V");
env->CallStaticVoidMethod(cls,
method,
javaSurface,
(int)aRect.x,
(int)aRect.y,
(int)aRect.width,
(int)aRect.height,
jMetadata);
#else
jmethodID method = env->GetStaticMethodID(cls,
"addPluginView",
"(Landroid/view/View;DDDD)V");
env->CallStaticVoidMethod(cls,
method,
javaSurface,
aRect.x,
aRect.y,
aRect.width,
aRect.height);
#endif
if (AndroidBridge::Bridge())
AndroidBridge::Bridge()->AddPluginView((jobject)javaSurface, aRect);
return true;
}
@ -1827,7 +1788,8 @@ void nsPluginInstanceOwner::RemovePluginView()
if (!surface)
return;
AndroidBridge::RemovePluginView(surface);
if (AndroidBridge::Bridge())
AndroidBridge::Bridge()->RemovePluginView((jobject)surface);
}
void nsPluginInstanceOwner::Invalidate() {
@ -2913,14 +2875,21 @@ void nsPluginInstanceOwner::Paint(gfxContext* aContext,
PRInt32 model = mInstance->GetANPDrawingModel();
float xResolution = mObjectFrame->PresContext()->GetRootPresContext()->PresShell()->GetXResolution();
float yResolution = mObjectFrame->PresContext()->GetRootPresContext()->PresShell()->GetYResolution();
// Get the offset of the content relative to the page
gfxRect scaledFrameRect = aFrameRect;
scaledFrameRect.Scale(xResolution, yResolution);
nsPoint offset = nsPoint(0, 0);
nsIFrame* current = (nsIFrame*)mObjectFrame;
while (current && current->GetContent() && current->GetContent()->Tag() != nsGkAtoms::html) {
offset += current->GetPosition();
current = current->GetParent();
}
nsRect bounds = nsRect(offset, mObjectFrame->GetSize());
nsIntRect intBounds = bounds.ToNearestPixels(mObjectFrame->PresContext()->AppUnitsPerDevPixel());
gfxRect pluginRect(intBounds);
if (model == kSurface_ANPDrawingModel) {
if (!AddPluginView(scaledFrameRect)) {
if (!AddPluginView(pluginRect)) {
Invalidate();
}
return;
@ -2930,9 +2899,13 @@ void nsPluginInstanceOwner::Paint(gfxContext* aContext,
if (!mLayer)
mLayer = new AndroidMediaLayer();
mLayer->UpdatePosition(scaledFrameRect, xResolution);
mLayer->UpdatePosition(pluginRect);
SendSize((int)scaledFrameRect.width, (int)scaledFrameRect.height);
float xResolution = mObjectFrame->PresContext()->GetRootPresContext()->PresShell()->GetXResolution();
float yResolution = mObjectFrame->PresContext()->GetRootPresContext()->PresShell()->GetYResolution();
pluginRect.Scale(xResolution, yResolution);
SendSize((int)pluginRect.width, (int)pluginRect.height);
return;
}

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

@ -18,6 +18,13 @@ LIBXUL_LIBRARY = 1
EXTRA_COMPONENTS = \
SettingsManager.js \
SettingsManager.manifest \
SettingsService.js \
SettingsService.manifest \
$(NULL)
EXTRA_JS_MODULES = \
SettingsQueue.jsm \
SettingsDB.jsm \
$(NULL)
ifdef ENABLE_TESTS

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

@ -0,0 +1,36 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
let EXPORTED_SYMBOLS = ["SettingsDB", "SETTINGSDB_NAME", "SETTINGSSTORE_NAME"];
/* static functions */
let DEBUG = 0;
if (DEBUG) {
debug = function (s) { dump("-*- SettingsDB: " + s + "\n"); }
} else {
debug = function (s) {}
}
const SETTINGSDB_NAME = "settings";
const SETTINGSDB_VERSION = 1;
const SETTINGSSTORE_NAME = "settings";
Components.utils.import("resource://gre/modules/IndexedDBHelper.jsm");
function SettingsDB() {}
SettingsDB.prototype = {
__proto__: IndexedDBHelper.prototype,
createSchema: function createSchema(aDb) {
let objectStore = aDb.createObjectStore(SETTINGSSTORE_NAME, { keyPath: "settingName" });
objectStore.createIndex("settingValue", "settingValue", { unique: false });
debug("Created object stores and indexes");
},
init: function init(aGlobal) {
this.initDBHelper(SETTINGSDB_NAME, SETTINGSDB_VERSION, SETTINGSSTORE_NAME, aGlobal);
}
}

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

@ -11,57 +11,12 @@ if (DEBUG)
else
debug = function (s) {}
function Queue() {
this._queue = [];
this._index = 0;
}
Queue.prototype = {
getLength: function() { return (this._queue.length - this._index); },
isEmpty: function() { return (this._queue.length == 0); },
enqueue: function(item) { this._queue.push(item); },
dequeue: function() {
if(this.isEmpty())
return undefined;
var item = this._queue[this._index];
if (++this._index * 2 >= this._queue.length){
this._queue = this._queue.slice(this._index);
this._index = 0;
}
return item;
}
}
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
Cu.import("resource://gre/modules/IndexedDBHelper.jsm");
const DB_NAME = "settings";
const DB_VERSION = 1;
const STORE_NAME = "settings";
function SettingsDB() {}
SettingsDB.prototype = {
__proto__: IndexedDBHelper.prototype,
createSchema: function createSchema(aDb) {
let objectStore = aDb.createObjectStore(STORE_NAME, { keyPath: "settingName" });
objectStore.createIndex("settingValue", "settingValue", { unique: false });
debug("Created object stores and indexes");
},
init: function init(aGlobal) {
this.initDBHelper(DB_NAME, DB_VERSION, STORE_NAME, aGlobal);
}
}
Cu.import("resource://gre/modules/SettingsQueue.jsm");
Cu.import("resource://gre/modules/SettingsDB.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
@ -83,7 +38,7 @@ SettingsLock.prototype = {
process: function process() {
let lock = this;
lock._open = false;
let store = lock._transaction.objectStore(STORE_NAME);
let store = lock._transaction.objectStore(SETTINGSSTORE_NAME);
while (!lock._requests.isEmpty()) {
let info = lock._requests.dequeue();
@ -152,7 +107,7 @@ SettingsLock.prototype = {
var lock;
while (lock = this._settingsManager._locks.dequeue()) {
if (!lock._transaction) {
lock._transaction = lock._settingsManager._settingsDB._db.transaction(STORE_NAME, "readwrite");
lock._transaction = lock._settingsManager._settingsDB._db.transaction(SETTINGSSTORE_NAME, "readwrite");
}
lock.process();
}

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

@ -0,0 +1,30 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
let EXPORTED_SYMBOLS = ["Queue"];
function Queue() {
this._queue = [];
this._index = 0;
}
Queue.prototype = {
getLength: function() { return (this._queue.length - this._index); },
isEmpty: function() { return (this._queue.length == 0); },
enqueue: function(item) { this._queue.push(item); },
dequeue: function() {
if(this.isEmpty())
return undefined;
var item = this._queue[this._index];
if (++this._index * 2 >= this._queue.length){
this._queue = this._queue.slice(this._index);
this._index = 0;
}
return item;
}
}

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

@ -0,0 +1,183 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict"
/* static functions */
let DEBUG = 0;
if (DEBUG)
debug = function (s) { dump("-*- SettingsService: " + s + "\n"); }
else
debug = function (s) {}
const Ci = Components.interfaces;
const Cu = Components.utils;
Cu.import("resource://gre/modules/SettingsQueue.jsm");
Cu.import("resource://gre/modules/SettingsDB.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
const nsIClassInfo = Ci.nsIClassInfo;
const SETTINGSSERVICELOCK_CONTRACTID = "@mozilla.org/settingsServiceLock;1";
const SETTINGSSERVICELOCK_CID = Components.ID("{3ab3cbc0-8513-11e1-b0c4-0800200c9a66}");
const nsISettingsServiceLock = Ci.nsISettingsServiceLock;
function SettingsServiceLock(aSettingsService)
{
debug("settingsServiceLock constr!");
this._open = true;
this._requests = new Queue();
this._settingsService = aSettingsService;
this._transaction = null;
}
SettingsServiceLock.prototype = {
process: function process() {
debug("process!");
let lock = this;
lock._open = false;
let store = lock._transaction.objectStore(SETTINGSSTORE_NAME);
while (!lock._requests.isEmpty()) {
let info = lock._requests.dequeue();
debug("info:" + info.intent);
let callback = info.callback;
let req;
let name = info.name;
switch (info.intent) {
case "set":
let value = info.value;
if(typeof(value) == 'object')
debug("object name:" + name + ", val: " + JSON.stringify(value));
req = store.put({settingName: name, settingValue: value});
req.onsuccess = function() {
debug("set on success");
lock._open = true;
if (callback)
callback.handle(name, value);
Services.obs.notifyObservers(lock, "mozsettings-changed", JSON.stringify({
key: name,
value: value
}));
lock._open = false;
};
req.onerror = function(event) { callback ? callback.handleError(event.target.errorMessage) : null; };
break;
case "get":
req = store.getAll(name);
req.onsuccess = function(event) {
debug("Request successful. Record count:" + event.target.result.length);
debug("result: " + JSON.stringify(event.target.result));
this._open = true;
if (callback) {
if (event.target.result[0]) {
if (event.target.result.length > 1) {
debug("Warning: overloaded setting:" + name);
}
callback.handle(name, event.target.result[0].settingValue);
} else
callback.handle(name, null);
} else {
debug("no callback defined!");
}
this._open = false;
}.bind(lock);
req.onerror = function error(event) { callback ? callback.handleError(event.target.errorMessage) : null; };
break;
}
}
if (!lock._requests.isEmpty())
throw Components.results.NS_ERROR_ABORT;
lock._open = true;
},
createTransactionAndProcess: function createTransactionAndProcess() {
if (this._settingsService._settingsDB._db) {
var lock;
while (lock = this._settingsService._locks.dequeue()) {
if (!lock._transaction) {
lock._transaction = lock._settingsService._settingsDB._db.transaction(SETTINGSSTORE_NAME, "readwrite");
}
lock.process();
}
if (!this._requests.isEmpty())
this.process();
}
},
get: function get(aName, aCallback) {
debug("get: " + aName + ", " + aCallback);
this._requests.enqueue({ callback: aCallback, intent:"get", name: aName });
this.createTransactionAndProcess();
},
set: function set(aName, aValue, aCallback) {
debug("set: " + aName + ": " + JSON.stringify(aValue));
this._requests.enqueue({ callback: aCallback, intent: "set", name: aName, value: aValue});
this.createTransactionAndProcess();
},
classID : SETTINGSSERVICELOCK_CID,
QueryInterface : XPCOMUtils.generateQI([nsISettingsServiceLock]),
classInfo : XPCOMUtils.generateCI({classID: SETTINGSSERVICELOCK_CID,
contractID: SETTINGSSERVICELOCK_CONTRACTID,
classDescription: "SettingsServiceLock",
interfaces: [nsISettingsServiceLock],
flags: nsIClassInfo.DOM_OBJECT})
};
const SETTINGSSERVICE_CONTRACTID = "@mozilla.org/settingsService;1";
const SETTINGSSERVICE_CID = Components.ID("{3458e760-8513-11e1-b0c4-0800200c9a66}");
const nsISettingsService = Ci.nsISettingsService;
let myGlobal = this;
function SettingsService()
{
debug("settingsService Constructor");
this._locks = new Queue();
var idbManager = Components.classes["@mozilla.org/dom/indexeddb/manager;1"].getService(Ci.nsIIndexedDatabaseManager);
idbManager.initWindowless(myGlobal);
this._settingsDB = new SettingsDB();
this._settingsDB.init(myGlobal);
}
SettingsService.prototype = {
nextTick: function nextTick(aCallback, thisObj) {
if (thisObj)
aCallback = aCallback.bind(thisObj);
Services.tm.currentThread.dispatch(aCallback, Ci.nsIThread.DISPATCH_NORMAL);
},
getLock: function getLock() {
debug("get lock!");
var lock = new SettingsServiceLock(this);
this._locks.enqueue(lock);
this._settingsDB.ensureDB(
function() { lock.createTransactionAndProcess(); },
function() { dump("ensureDB error cb!\n"); },
myGlobal );
this.nextTick(function() { this._open = false; }, lock);
return lock;
},
classID : SETTINGSSERVICE_CID,
QueryInterface : XPCOMUtils.generateQI([nsISettingsService]),
classInfo : XPCOMUtils.generateCI({classID: SETTINGSSERVICE_CID,
contractID: SETTINGSSERVICE_CONTRACTID,
classDescription: "SettingsService",
interfaces: [nsISettingsService],
flags: nsIClassInfo.DOM_OBJECT})
}
const NSGetFactory = XPCOMUtils.generateNSGetFactory([SettingsService, SettingsServiceLock])

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

@ -0,0 +1,5 @@
component {3ab3cbc0-8513-11e1-b0c4-0800200c9a66} SettingsService.js
contract @mozilla.org/settingsServiceLock;1 {3ab3cbc0-8513-11e1-b0c4-0800200c9a66}
component {3458e760-8513-11e1-b0c4-0800200c9a66} SettingsService.js
contract @mozilla.org/settingsService;1 {3458e760-8513-11e1-b0c4-0800200c9a66}

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

@ -11,9 +11,6 @@ relativesrcdir = dom/settings/tests
include $(DEPTH)/config/autoconf.mk
DIRS = \
$(NULL)
include $(topsrcdir)/config/rules.mk
_TEST_FILES = \

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

@ -78,6 +78,7 @@ _TEST_FILES = \
test_callback_wrapping.xul \
window_callback_wrapping.xul \
test_sandbox_postMessage.html \
test_sandbox_bindings.xul \
$(NULL)
ifeq (WINNT,$(OS_ARCH))

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

@ -0,0 +1,52 @@
<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=741267
-->
<window title="Mozilla Bug 741267"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
<iframe id="t"></iframe>
<!-- test results are displayed in the html:body -->
<body xmlns="http://www.w3.org/1999/xhtml">
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=741267"
target="_blank">Mozilla Bug 741267</a>
</body>
<!-- test code goes here -->
<script type="application/javascript">
<![CDATA[
/** Test for Bug 741267 **/
function doTest() {
var win = $("t").contentWindow;
var sandbox = Components.utils.Sandbox(win, { sandboxPrototype: win });
try {
var nl = Components.utils.evalInSandbox("NodeList", sandbox);
is(nl, "[object NodeList]", "'NodeList' in a sandbox should return the NodeList interface prototype object");
} catch (e) {
ok(false, "'NodeList' shouldn't throw in a sandbox");
}
try {
var et = Components.utils.evalInSandbox("EventTarget", sandbox);
ok(et, "'EventTarget' in a sandbox should return the EventTarget interface prototype object");
} catch (e) {
ok(false, "'EventTarget' shouldn't throw in a sandbox");
}
try {
var xhr = Components.utils.evalInSandbox("XMLHttpRequest()", sandbox);
is(xhr, "[object XMLHttpRequest]", "'XMLHttpRequest()' in a sandbox should create an XMLHttpRequest object");
} catch (e) {
ok(false, "'XMLHttpRequest()' shouldn't throw in a sandbox");
}
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
addLoadEvent(doTest);
]]>
</script>
</window>

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

@ -76,6 +76,7 @@ _TEST_FILES = \
test_focus_legend_noparent.html \
file_clonewrapper.html \
file_moving_nodeList.html \
test_performance_now.html \
$(NULL)
_CHROME_FILES = \

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

@ -0,0 +1,23 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for High Resolution Timer</title>
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<script>
ok(window.performance);
ok(typeof window.performance.now == 'function');
var n = window.performance.now();
ok(n >= 0);
ok(window.performance.now() >= n);
SimpleTest.waitForExplicitFinish();
setTimeout(function() {
ok(window.performance.now() > n);
SimpleTest.finish();
}, 20);
</script>
</body>
</html>

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

@ -37,7 +37,7 @@ struct WrapPrototypeTraits
GetProtoObject(JSContext* aCx, JSObject* aGlobal) \
{ \
using namespace mozilla::dom::bindings::prototypes; \
return _class##_workers::GetProtoObject(aCx, aGlobal); \
return _class##_workers::GetProtoObject(aCx, aGlobal, aGlobal); \
} \
};

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

@ -449,7 +449,7 @@ ResolveWorkerClasses(JSContext* aCx, JSObject* aObj, jsid aId, unsigned aFlags,
return true;
}
JSObject* eventTarget = EventTarget_workers::GetProtoObject(aCx, aObj);
JSObject* eventTarget = EventTarget_workers::GetProtoObject(aCx, aObj, aObj);
if (!eventTarget) {
return false;
}

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

@ -958,7 +958,8 @@ CreateDedicatedWorkerGlobalScope(JSContext* aCx)
// -> EventTarget
// -> Object
JSObject* eventTargetProto = EventTarget_workers::GetProtoObject(aCx, global);
JSObject* eventTargetProto =
EventTarget_workers::GetProtoObject(aCx, global, global);
if (!eventTargetProto) {
return NULL;
}
@ -1003,8 +1004,9 @@ CreateDedicatedWorkerGlobalScope(JSContext* aCx)
}
// Init other paris-bindings.
if (!XMLHttpRequest_workers::CreateInterfaceObjects(aCx, global) ||
!XMLHttpRequestUpload_workers::CreateInterfaceObjects(aCx, global)) {
if (!XMLHttpRequest_workers::CreateInterfaceObjects(aCx, global, global) ||
!XMLHttpRequestUpload_workers::CreateInterfaceObjects(aCx, global,
global)) {
return NULL;
}

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

@ -1826,9 +1826,6 @@ public class GeckoAppShell
return false;
}
public static void emitGeckoAccessibilityEvent (int eventType, String[] textList, String description, boolean enabled, boolean checked, boolean password) {
}
public static double[] getCurrentNetworkInformation() {
return GeckoNetworkManager.getInstance().getCurrentInformation();
}

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

@ -641,6 +641,11 @@ GLContext::CanUploadSubTextures()
if (!mWorkAroundDriverBugs)
return true;
// Lock surface feature allows to mmap texture memory and modify it directly
// this feature allow us modify texture partially without full upload
if (HasLockSurface())
return true;
// There are certain GPUs that we don't want to use glTexSubImage2D on
// because that function can be very slow and/or buggy
if (Renderer() == RendererAdreno200 || Renderer() == RendererAdreno205)

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

@ -731,6 +731,7 @@ public:
bool CanUploadSubTextures();
bool CanUploadNonPowerOfTwo();
bool WantsSmallTiles();
virtual bool HasLockSurface() { return false; }
/**
* If this context wraps a double-buffered target, swap the back

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

@ -597,6 +597,10 @@ public:
return h;
}
virtual bool HasLockSurface() {
return sEGLLibrary.HasKHRLockSurface();
}
protected:
friend class GLContextProviderEGL;

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

@ -817,8 +817,13 @@ LayerManagerOGL::Render()
mGLContext->fEnable(LOCAL_GL_SCISSOR_TEST);
// If the Java compositor is being used, this clear will be done in
// DrawWindowUnderlay. Make sure the bits used here match up with those used
// in mobile/android/base/gfx/LayerRenderer.java
#ifndef MOZ_JAVA_COMPOSITOR
mGLContext->fClearColor(0.0, 0.0, 0.0, 0.0);
mGLContext->fClear(LOCAL_GL_COLOR_BUFFER_BIT | LOCAL_GL_DEPTH_BUFFER_BIT);
#endif
// Allow widget to render a custom background.
mWidget->DrawWindowUnderlay(this, rect);

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