mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-08 12:37:37 +00:00
Merge mozilla-central into services-central
This commit is contained in:
commit
92d1fbddef
@ -30,7 +30,7 @@ public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
// nsIAccessibleTable
|
||||
NS_DECL_OR_FORWARD_NSIACCESSIBLETABLE_WITH_XPCACCESSIBLETABLE
|
||||
NS_FORWARD_NSIACCESSIBLETABLE(xpcAccessibleTable::)
|
||||
|
||||
// Accessible
|
||||
virtual TableAccessible* AsTable() { return this; }
|
||||
|
@ -95,7 +95,7 @@ public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
// nsIAccessible Table
|
||||
NS_DECL_OR_FORWARD_NSIACCESSIBLETABLE_WITH_XPCACCESSIBLETABLE
|
||||
NS_FORWARD_NSIACCESSIBLETABLE(xpcAccessibleTable::)
|
||||
|
||||
// TableAccessible
|
||||
virtual Accessible* Caption();
|
||||
|
@ -65,65 +65,4 @@ protected:
|
||||
mozilla::a11y::TableAccessible* mTable;
|
||||
};
|
||||
|
||||
#define NS_DECL_OR_FORWARD_NSIACCESSIBLETABLE_WITH_XPCACCESSIBLETABLE \
|
||||
NS_IMETHOD GetCaption(nsIAccessible** aCaption) \
|
||||
{ return xpcAccessibleTable::GetCaption(aCaption); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetSummary(nsAString & aSummary) \
|
||||
{ return xpcAccessibleTable::GetSummary(aSummary); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetColumnCount(PRInt32* aColumnCount) \
|
||||
{ return xpcAccessibleTable::GetColumnCount(aColumnCount); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetRowCount(PRInt32* aRowCount) \
|
||||
{ return xpcAccessibleTable::GetRowCount(aRowCount); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetCellAt(PRInt32 rowIndex, PRInt32 columnIndex, nsIAccessible** _retval NS_OUTPARAM) \
|
||||
{ return xpcAccessibleTable::GetCellAt(rowIndex, columnIndex, _retval); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetCellIndexAt(PRInt32 rowIndex, PRInt32 columnIndex, PRInt32 *_retval NS_OUTPARAM) \
|
||||
{ return xpcAccessibleTable::GetCellIndexAt(rowIndex, columnIndex, _retval); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetColumnIndexAt(PRInt32 cellIndex, PRInt32 *_retval NS_OUTPARAM) \
|
||||
{ return xpcAccessibleTable::GetColumnIndexAt(cellIndex, _retval); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetRowIndexAt(PRInt32 cellIndex, PRInt32 *_retval NS_OUTPARAM) \
|
||||
{ return xpcAccessibleTable::GetRowIndexAt(cellIndex, _retval); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetRowAndColumnIndicesAt(PRInt32 cellIndex, PRInt32 *rowIndex NS_OUTPARAM, PRInt32 *columnIndex NS_OUTPARAM) \
|
||||
{ return xpcAccessibleTable::GetRowAndColumnIndicesAt(cellIndex, rowIndex, columnIndex); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetColumnExtentAt(PRInt32 row, PRInt32 column, PRInt32* _retval NS_OUTPARAM) \
|
||||
{ return xpcAccessibleTable::GetColumnExtentAt(row, column, _retval); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetRowExtentAt(PRInt32 row, PRInt32 column, PRInt32* _retval NS_OUTPARAM) \
|
||||
{ return xpcAccessibleTable::GetRowExtentAt(row, column, _retval); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetColumnDescription(PRInt32 columnIndex, nsAString& _retval NS_OUTPARAM) \
|
||||
{ return xpcAccessibleTable::GetColumnDescription(columnIndex, _retval); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetRowDescription(PRInt32 rowIndex, nsAString& _retval NS_OUTPARAM) \
|
||||
{ return xpcAccessibleTable::GetRowDescription(rowIndex, _retval); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD IsColumnSelected(PRInt32 colIdx, bool* _retval NS_OUTPARAM) \
|
||||
{ return xpcAccessibleTable::IsColumnSelected(colIdx, _retval); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD IsRowSelected(PRInt32 rowIdx, bool* _retval NS_OUTPARAM) \
|
||||
{ return xpcAccessibleTable::IsRowSelected(rowIdx, _retval); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD IsCellSelected(PRInt32 rowIdx, PRInt32 colIdx, bool* _retval NS_OUTPARAM) \
|
||||
{ return xpcAccessibleTable::IsCellSelected(rowIdx, colIdx, _retval); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetSelectedCellCount(PRUint32* aSelectedCellCount) \
|
||||
{ return xpcAccessibleTable::GetSelectedCellCount(aSelectedCellCount); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetSelectedColumnCount(PRUint32* aSelectedColumnCount) \
|
||||
{ return xpcAccessibleTable::GetSelectedColumnCount(aSelectedColumnCount); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetSelectedRowCount(PRUint32* aSelectedRowCount) \
|
||||
{ return xpcAccessibleTable::GetSelectedRowCount(aSelectedRowCount); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetSelectedCells(nsIArray** aSelectedCells) \
|
||||
{ return xpcAccessibleTable::GetSelectedCells(aSelectedCells); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetSelectedCellIndices(PRUint32* cellsArraySize NS_OUTPARAM, \
|
||||
PRInt32** cellsArray NS_OUTPARAM) \
|
||||
{ return xpcAccessibleTable::GetSelectedCellIndices(cellsArraySize, cellsArray); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetSelectedColumnIndices(PRUint32* colsArraySize NS_OUTPARAM, \
|
||||
PRInt32** colsArray NS_OUTPARAM) \
|
||||
{ return xpcAccessibleTable::GetSelectedColumnIndices(colsArraySize, colsArray); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetSelectedRowIndices(PRUint32* rowsArraySize NS_OUTPARAM, \
|
||||
PRInt32** rowsArray NS_OUTPARAM) \
|
||||
{ return xpcAccessibleTable::GetSelectedRowIndices(rowsArraySize, rowsArray); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD SelectRow(PRInt32 aRowIdx) \
|
||||
{ return xpcAccessibleTable::SelectRow(aRowIdx); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD SelectColumn(PRInt32 aColIdx) \
|
||||
{ return xpcAccessibleTable::SelectColumn(aColIdx); } \
|
||||
NS_SCRIPTABLE NS_IMETHOD UnselectColumn(PRInt32 aColIdx) \
|
||||
{ return xpcAccessibleTable::UnselectColumn(aColIdx); } \
|
||||
NS_IMETHOD UnselectRow(PRInt32 aRowIdx) \
|
||||
{ return xpcAccessibleTable::UnselectRow(aRowIdx); } \
|
||||
NS_IMETHOD IsProbablyForLayout(bool* aResult) \
|
||||
{ return xpcAccessibleTable::IsProbablyForLayout(aResult); } \
|
||||
|
||||
#endif // MOZILLA_A11Y_XPCOM_XPACCESSIBLETABLE_H_
|
||||
|
@ -70,7 +70,7 @@ public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
// nsIAccessibleTable
|
||||
NS_DECL_OR_FORWARD_NSIACCESSIBLETABLE_WITH_XPCACCESSIBLETABLE
|
||||
NS_FORWARD_NSIACCESSIBLETABLE(xpcAccessibleTable::)
|
||||
|
||||
// TableAccessible
|
||||
virtual PRUint32 ColCount();
|
||||
|
@ -28,7 +28,7 @@ public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
// nsIAccessibleTable
|
||||
NS_DECL_OR_FORWARD_NSIACCESSIBLETABLE_WITH_XPCACCESSIBLETABLE
|
||||
NS_FORWARD_NSIACCESSIBLETABLE(xpcAccessibleTable::)
|
||||
|
||||
// TableAccessible
|
||||
virtual PRUint32 ColCount();
|
||||
|
@ -53,7 +53,8 @@ let FormAssistant = {
|
||||
checkbox: true,
|
||||
radio: true,
|
||||
reset: true,
|
||||
submit: true
|
||||
submit: true,
|
||||
image: true
|
||||
};
|
||||
|
||||
if (evt.target instanceof HTMLSelectElement) {
|
||||
@ -156,6 +157,10 @@ let FormAssistant = {
|
||||
},
|
||||
|
||||
tryShowIme: function(element) {
|
||||
if (!element) {
|
||||
return;
|
||||
}
|
||||
|
||||
// FIXME/bug 729623: work around apparent bug in the IME manager
|
||||
// in gecko.
|
||||
let readonly = element.getAttribute("readonly");
|
||||
|
@ -43,6 +43,10 @@ XPCOMUtils.defineLazyGetter(this, 'DebuggerServer', function() {
|
||||
return DebuggerServer;
|
||||
});
|
||||
|
||||
function getContentWindow() {
|
||||
return shell.contentBrowser.contentWindow;
|
||||
}
|
||||
|
||||
// FIXME Bug 707625
|
||||
// until we have a proper security model, add some rights to
|
||||
// the pre-installed web applications
|
||||
|
@ -34,7 +34,7 @@ ContentPermissionPrompt.prototype = {
|
||||
return;
|
||||
|
||||
let browser = Services.wm.getMostRecentWindow("navigator:browser");
|
||||
let content = browser.content;
|
||||
let content = browser.getContentWindow();
|
||||
if (!content)
|
||||
return;
|
||||
|
||||
@ -42,8 +42,8 @@ ContentPermissionPrompt.prototype = {
|
||||
content.addEventListener("mozContentEvent", function contentEvent(evt) {
|
||||
if (evt.detail.id != requestId)
|
||||
return;
|
||||
evt.target.removeEventListener(evt.type, contentEvent);
|
||||
|
||||
content.removeEventListener(evt.type, contentEvent);
|
||||
if (evt.detail.type == "permission-allow") {
|
||||
request.allow();
|
||||
return;
|
||||
@ -52,10 +52,15 @@ ContentPermissionPrompt.prototype = {
|
||||
request.cancel();
|
||||
});
|
||||
|
||||
browser.shell.sendEvent(browser.content, "mozChromeEvent", {
|
||||
"type": "permission-prompt", "permission": request.type,
|
||||
"id": requestId, "url": request.uri.spec
|
||||
});
|
||||
let details = {
|
||||
"type": "permission-prompt",
|
||||
"permission": request.type,
|
||||
"id": requestId,
|
||||
"url": request.uri.spec
|
||||
};
|
||||
let event = content.document.createEvent("CustomEvent");
|
||||
event.initCustomEvent("mozChromeEvent", true, true, details);
|
||||
content.dispatchEvent(event);
|
||||
},
|
||||
|
||||
classID: Components.ID("{8c719f03-afe0-4aac-91ff-6c215895d467}"),
|
||||
|
@ -140,6 +140,12 @@ var gPluginHandler = {
|
||||
self.pluginUnavailable(plugin, event.type);
|
||||
break;
|
||||
|
||||
case "PluginVulnerableUpdatable":
|
||||
let updateLink = doc.getAnonymousElementByAttribute(plugin, "class", "checkForUpdatesLink");
|
||||
self.addLinkClickCallback(updateLink, "openPluginUpdatePage");
|
||||
/* FALLTHRU */
|
||||
|
||||
case "PluginVulnerableNoUpdate":
|
||||
case "PluginClickToPlay":
|
||||
self._handleClickToPlayEvent(plugin);
|
||||
break;
|
||||
@ -151,9 +157,10 @@ var gPluginHandler = {
|
||||
}
|
||||
|
||||
// Hide the in-content UI if it's too big. The crashed plugin handler already did this.
|
||||
if (event.type != "PluginCrashed" && event.type != "PluginClickToPlay") {
|
||||
if (event.type != "PluginCrashed") {
|
||||
let overlay = doc.getAnonymousElementByAttribute(plugin, "class", "mainBox");
|
||||
if (self.isTooSmall(plugin, overlay))
|
||||
/* overlay might be null, so only operate on it if it exists */
|
||||
if (overlay != null && self.isTooSmall(plugin, overlay))
|
||||
overlay.style.visibility = "hidden";
|
||||
}
|
||||
},
|
||||
@ -224,6 +231,12 @@ var gPluginHandler = {
|
||||
managePlugins: function (aEvent) {
|
||||
BrowserOpenAddonsMgr("addons://list/plugin");
|
||||
},
|
||||
|
||||
// Callback for user clicking on the link in a click-to-play plugin
|
||||
// (where the plugin has an update)
|
||||
openPluginUpdatePage: function (aEvent) {
|
||||
openURL(Services.urlFormatter.formatURLPref("plugins.update.url"));
|
||||
},
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
// Callback for user clicking "submit a report" link
|
||||
@ -258,15 +271,18 @@ var gPluginHandler = {
|
||||
objLoadingContent.playPlugin();
|
||||
return;
|
||||
} else if (pluginsPermission == Ci.nsIPermissionManager.DENY_ACTION) {
|
||||
overlay.style.visibility = "hidden";
|
||||
if (overlay)
|
||||
overlay.style.visibility = "hidden";
|
||||
return;
|
||||
}
|
||||
|
||||
let overlay = doc.getAnonymousElementByAttribute(aPlugin, "class", "mainBox");
|
||||
// The overlay is null if the XBL binding is not attached (element is display:none).
|
||||
if (overlay) {
|
||||
overlay.addEventListener("click", function(aEvent) {
|
||||
if (aEvent.button == 0 && aEvent.isTrusted)
|
||||
// Have to check that the target is a XULElement and not the link
|
||||
// to update the plugin
|
||||
if (aEvent.target instanceof XULElement &&
|
||||
aEvent.button == 0 && aEvent.isTrusted)
|
||||
gPluginHandler.activateSinglePlugin(aEvent.target.ownerDocument.defaultView.top, aPlugin);
|
||||
}, true);
|
||||
}
|
||||
|
@ -1001,6 +1001,8 @@ var gBrowserInit = {
|
||||
gBrowser.addEventListener("PluginOutdated", gPluginHandler, true);
|
||||
gBrowser.addEventListener("PluginDisabled", gPluginHandler, true);
|
||||
gBrowser.addEventListener("PluginClickToPlay", gPluginHandler, true);
|
||||
gBrowser.addEventListener("PluginVulnerableUpdatable", gPluginHandler, true);
|
||||
gBrowser.addEventListener("PluginVulnerableNoUpdate", gPluginHandler, true);
|
||||
gBrowser.addEventListener("NewPluginInstalled", gPluginHandler.newPluginInstalled, true);
|
||||
#ifdef XP_MACOSX
|
||||
gBrowser.addEventListener("npapi-carbon-event-model-failure", gPluginHandler, true);
|
||||
|
@ -517,5 +517,103 @@ function test17() {
|
||||
var missingNotification = PopupNotifications.getNotification("missing-plugins", gTestBrowser);
|
||||
ok(!missingNotification, "Test 17, Should not have a missing plugin notification");
|
||||
|
||||
registerFakeBlocklistService(Ci.nsIBlocklistService.STATE_VULNERABLE_UPDATE_AVAILABLE);
|
||||
prepareTest(test18a, gTestRoot + "plugin_test.html");
|
||||
}
|
||||
|
||||
const Cr = Components.results;
|
||||
const Cm = Components.manager;
|
||||
const Cc = Components.classes;
|
||||
const gReg = Cm.QueryInterface(Ci.nsIComponentRegistrar);
|
||||
const gRealBlocklistServiceCID = Cc["@mozilla.org/extensions/blocklist;1"];
|
||||
const gFakeBlocklistServiceCID = Components.ID("{614b68a0-3c53-4ec0-8146-28cc1e25f8a1}");
|
||||
var gFactory = null;
|
||||
|
||||
function registerFakeBlocklistService(blockState) {
|
||||
|
||||
var BlocklistService = {
|
||||
getPluginBlocklistState: function(plugin, appVersion, toolkitVersion) {
|
||||
return blockState;
|
||||
},
|
||||
|
||||
classID: gFakeBlocklistServiceCID,
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIBlocklistService])
|
||||
};
|
||||
|
||||
gFactory = {
|
||||
createInstance: function(outer, iid) {
|
||||
if (outer != null)
|
||||
throw Cr.NS_ERROR_NO_AGGREGATION;
|
||||
return BlocklistService.QueryInterface(iid);
|
||||
}
|
||||
};
|
||||
|
||||
gReg.registerFactory(gFakeBlocklistServiceCID,
|
||||
"Fake Blocklist Service",
|
||||
"@mozilla.org/extensions/blocklist;1",
|
||||
gFactory);
|
||||
}
|
||||
|
||||
function unregisterFakeBlocklistService() {
|
||||
if (gFactory != null ) {
|
||||
gReg.unregisterFactory(gFakeBlocklistServiceCID, gFactory);
|
||||
gFactory = null;
|
||||
// This should restore the original blocklist service:
|
||||
gReg.registerFactory(gRealBlocklistServiceCID,
|
||||
"Blocklist Service",
|
||||
"@mozilla.org/extensions/blocklist;1",
|
||||
null);
|
||||
}
|
||||
}
|
||||
|
||||
// Tests a vulnerable, updatable plugin
|
||||
function test18a() {
|
||||
var clickToPlayNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
|
||||
ok(clickToPlayNotification, "Test 18a, Should have a click-to-play notification");
|
||||
var doc = gTestBrowser.contentDocument;
|
||||
var plugin = doc.getElementById("test");
|
||||
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
ok(!objLoadingContent.activated, "Test 18a, Plugin should not be activated");
|
||||
var overlay = doc.getAnonymousElementByAttribute(plugin, "class", "mainBox");
|
||||
ok(overlay.style.visibility != "hidden", "Test 18a, Plugin overlay should exist, not be hidden");
|
||||
var updateLink = doc.getAnonymousElementByAttribute(plugin, "class", "checkForUpdatesLink");
|
||||
ok(updateLink.style.visibility != "hidden", "Test 18a, Plugin should have an update link");
|
||||
|
||||
var tabOpenListener = new TabOpenListener(Services.urlFormatter.formatURLPref("plugins.update.url"), false, false);
|
||||
tabOpenListener.handleEvent = function(event) {
|
||||
if (event.type == "TabOpen") {
|
||||
gBrowser.tabContainer.removeEventListener("TabOpen", this, false);
|
||||
this.tab = event.originalTarget;
|
||||
ok(event.target.label == this.url, "Test 18a, Update link should open up the plugin check page");
|
||||
gBrowser.removeTab(this.tab);
|
||||
test18b();
|
||||
}
|
||||
};
|
||||
EventUtils.synthesizeMouse(updateLink, 5, 5, {}, gTestBrowser.contentWindow);
|
||||
}
|
||||
|
||||
function test18b() {
|
||||
unregisterFakeBlocklistService();
|
||||
registerFakeBlocklistService(Ci.nsIBlocklistService.STATE_VULNERABLE_NO_UPDATE);
|
||||
prepareTest(test18c, gTestRoot + "plugin_test.html");
|
||||
}
|
||||
|
||||
// Tests a vulnerable plugin with no update
|
||||
function test18c() {
|
||||
var clickToPlayNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
|
||||
ok(clickToPlayNotification, "Test 18c, Should have a click-to-play notification");
|
||||
var doc = gTestBrowser.contentDocument;
|
||||
var plugin = doc.getElementById("test");
|
||||
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
ok(!objLoadingContent.activated, "Test 18c, Plugin should not be activated");
|
||||
var overlay = doc.getAnonymousElementByAttribute(plugin, "class", "mainBox");
|
||||
ok(overlay.style.visibility != "hidden", "Test 18c, Plugin overlay should exist, not be hidden");
|
||||
var updateLink = doc.getAnonymousElementByAttribute(plugin, "class", "checkForUpdatesLink");
|
||||
ok(updateLink.style.display != "block", "Test 18c, Plugin should not have an update link");
|
||||
|
||||
unregisterFakeBlocklistService();
|
||||
var plugin = get_test_plugin();
|
||||
plugin.clicktoplay = false;
|
||||
|
||||
finishTest();
|
||||
}
|
||||
|
@ -57,6 +57,7 @@ MOCHITEST_BROWSER_TESTS = \
|
||||
browser_dbg_pause-exceptions.js \
|
||||
browser_dbg_multiple-windows.js \
|
||||
browser_dbg_menustatus.js \
|
||||
browser_dbg_bfcache.js \
|
||||
head.js \
|
||||
$(NULL)
|
||||
|
||||
|
118
browser/devtools/debugger/test/browser_dbg_bfcache.js
Normal file
118
browser/devtools/debugger/test/browser_dbg_bfcache.js
Normal file
@ -0,0 +1,118 @@
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Make sure that the debugger is updated with the correct scripts when moving
|
||||
* back and forward in the tab.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "browser_dbg_script-switching.html";
|
||||
var gPane = null;
|
||||
var gTab = null;
|
||||
var gDebuggee = null;
|
||||
var gDebugger = null;
|
||||
var gScripts = null;
|
||||
|
||||
function test()
|
||||
{
|
||||
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPane = aPane;
|
||||
gDebugger = gPane.contentWindow;
|
||||
|
||||
testInitialLoad();
|
||||
});
|
||||
}
|
||||
|
||||
function testInitialLoad() {
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
|
||||
executeSoon(function() {
|
||||
validateFirstPage();
|
||||
testLocationChange();
|
||||
});
|
||||
});
|
||||
|
||||
gDebuggee.firstCall();
|
||||
}
|
||||
|
||||
function testLocationChange()
|
||||
{
|
||||
gDebugger.DebuggerController.activeThread.resume(function() {
|
||||
gDebugger.DebuggerController.client.addOneTimeListener("tabAttached", function(aEvent, aPacket) {
|
||||
ok(true, "Successfully reattached to the tab again.");
|
||||
gDebugger.DebuggerController.client.addOneTimeListener("resumed", function(aEvent, aPacket) {
|
||||
executeSoon(function() {
|
||||
validateSecondPage();
|
||||
testBack();
|
||||
});
|
||||
});
|
||||
});
|
||||
content.location = STACK_URL;
|
||||
});
|
||||
}
|
||||
|
||||
function testBack()
|
||||
{
|
||||
gDebugger.DebuggerController.client.addOneTimeListener("tabAttached", function(aEvent, aPacket) {
|
||||
ok(true, "Successfully reattached to the tab after going back.");
|
||||
gDebugger.DebuggerController.client.addOneTimeListener("resumed", function(aEvent, aPacket) {
|
||||
executeSoon(function() {
|
||||
validateFirstPage();
|
||||
testForward();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
info("Going back.");
|
||||
content.history.back();
|
||||
}
|
||||
|
||||
function testForward()
|
||||
{
|
||||
gDebugger.DebuggerController.client.addOneTimeListener("tabAttached", function(aEvent, aPacket) {
|
||||
ok(true, "Successfully reattached to the tab after going forward.");
|
||||
gDebugger.DebuggerController.client.addOneTimeListener("resumed", function(aEvent, aPacket) {
|
||||
executeSoon(function() {
|
||||
validateSecondPage();
|
||||
closeDebuggerAndFinish();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
info("Going forward.");
|
||||
content.history.forward();
|
||||
}
|
||||
|
||||
function validateFirstPage() {
|
||||
gScripts = gDebugger.DebuggerView.Scripts._scripts;
|
||||
|
||||
is(gScripts.itemCount, 2, "Found the expected number of scripts.");
|
||||
|
||||
let label1 = "test-script-switching-01.js";
|
||||
let label2 = "test-script-switching-02.js";
|
||||
|
||||
ok(gDebugger.DebuggerView.Scripts.containsLabel(label1),
|
||||
"Found the first script label.");
|
||||
ok(gDebugger.DebuggerView.Scripts.containsLabel(label2),
|
||||
"Found the second script label.");
|
||||
}
|
||||
|
||||
function validateSecondPage() {
|
||||
gScripts = gDebugger.DebuggerView.Scripts._scripts;
|
||||
|
||||
is(gScripts.itemCount, 1, "Found the expected number of scripts.");
|
||||
|
||||
ok(gDebugger.DebuggerView.Scripts.containsLabel("browser_dbg_stack.html"),
|
||||
"Found the single script label.");
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gDebugger = null;
|
||||
gScripts = null;
|
||||
});
|
@ -509,7 +509,28 @@ class DeviceManager:
|
||||
success: True
|
||||
failure: False
|
||||
"""
|
||||
|
||||
|
||||
@staticmethod
|
||||
def _escapedCommandLine(cmd):
|
||||
""" Utility function to return escaped and quoted version of command line """
|
||||
quotedCmd = []
|
||||
|
||||
for arg in cmd:
|
||||
arg.replace('&', '\&')
|
||||
|
||||
needsQuoting = False
|
||||
for char in [ ' ', '(', ')', '"', '&' ]:
|
||||
if arg.find(char) >= 0:
|
||||
needsQuoting = True
|
||||
break
|
||||
if needsQuoting:
|
||||
arg = '\'%s\'' % arg
|
||||
|
||||
quotedCmd.append(arg)
|
||||
|
||||
return " ".join(quotedCmd)
|
||||
|
||||
|
||||
class NetworkTools:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
@ -95,24 +95,13 @@ class DeviceManagerADB(DeviceManager):
|
||||
# success: <return code>
|
||||
# failure: None
|
||||
def shell(self, cmd, outputfile, env=None, cwd=None):
|
||||
# need to quote and escape special characters here
|
||||
for (index, arg) in enumerate(cmd):
|
||||
arg.replace('&', '\&')
|
||||
|
||||
needsQuoting = False
|
||||
for char in [ ' ', '(', ')', '"', '&' ]:
|
||||
if arg.find(char):
|
||||
needsQuoting = True
|
||||
break
|
||||
if needsQuoting:
|
||||
cmd[index] = '\'%s\'' % arg
|
||||
|
||||
# This is more complex than you'd think because adb doesn't actually
|
||||
# return the return code from a process, so we have to capture the output
|
||||
# to get it
|
||||
# FIXME: this function buffers all output of the command into memory,
|
||||
# always. :(
|
||||
cmdline = " ".join(cmd) + "; echo $?"
|
||||
|
||||
# Getting the return code is more complex than you'd think because adb
|
||||
# doesn't actually return the return code from a process, so we have to
|
||||
# capture the output to get it
|
||||
cmdline = "%s; echo $?" % self._escapedCommandLine(cmd)
|
||||
|
||||
# prepend cwd and env to command if necessary
|
||||
if cwd:
|
||||
|
@ -260,7 +260,7 @@ class DeviceManagerSUT(DeviceManager):
|
||||
# success: <return code>
|
||||
# failure: None
|
||||
def shell(self, cmd, outputfile, env=None, cwd=None):
|
||||
cmdline = subprocess.list2cmdline(cmd)
|
||||
cmdline = self._escapedCommandLine(cmd)
|
||||
if env:
|
||||
cmdline = '%s %s' % (self.formatEnvString(env), cmdline)
|
||||
|
||||
|
@ -191,7 +191,7 @@ endif
|
||||
|
||||
profiledbuild::
|
||||
$(MAKE) -f $(TOPSRCDIR)/client.mk realbuild MOZ_PROFILE_GENERATE=1 MOZ_PGO_INSTRUMENTED=1
|
||||
$(MAKE) -C $(PGO_OBJDIR) stage-package MOZ_PGO_INSTRUMENTED=1
|
||||
$(MAKE) -C $(PGO_OBJDIR) package MOZ_PGO_INSTRUMENTED=1 MOZ_INTERNAL_SIGNING_FORMAT= MOZ_EXTERNAL_SIGNING_FORMAT=
|
||||
MOZ_PGO_INSTRUMENTED=1 OBJDIR=${PGO_OBJDIR} JARLOG_DIR=${PGO_OBJDIR}/jarlog/en-US $(PROFILE_GEN_SCRIPT)
|
||||
$(MAKE) -f $(TOPSRCDIR)/client.mk maybe_clobber_profiledbuild
|
||||
$(MAKE) -f $(TOPSRCDIR)/client.mk realbuild MOZ_PROFILE_USE=1
|
||||
|
@ -4039,7 +4039,7 @@ MOZ_ZLIB_CHECK([1.2.3])
|
||||
|
||||
if test "$MOZ_NATIVE_ZLIB" != 1; then
|
||||
MOZ_ZLIB_CFLAGS=
|
||||
MOZ_ZLIB_LIBS='$(call EXPAND_LIBNAME_PATH,mozz,'"$_objdir"'/modules/zlib/src)'
|
||||
MOZ_ZLIB_LIBS='$(call EXPAND_LIBNAME_PATH,mozz,'"$MOZ_BUILD_ROOT"'/modules/zlib/src)'
|
||||
fi
|
||||
|
||||
if test "$MOZ_LINKER" = 1 -a "$MOZ_NATIVE_ZLIB" != 1; then
|
||||
|
@ -80,20 +80,6 @@ static PRLogModuleInfo* gObjectLog = PR_NewLogModule("objlc");
|
||||
#define LOG(args) PR_LOG(gObjectLog, PR_LOG_DEBUG, args)
|
||||
#define LOG_ENABLED() PR_LOG_TEST(gObjectLog, PR_LOG_DEBUG)
|
||||
|
||||
#include "mozilla/Preferences.h"
|
||||
|
||||
static bool gClickToPlayPlugins = false;
|
||||
|
||||
static void
|
||||
InitPrefCache()
|
||||
{
|
||||
static bool initializedPrefCache = false;
|
||||
if (!initializedPrefCache) {
|
||||
mozilla::Preferences::AddBoolVarCache(&gClickToPlayPlugins, "plugins.click_to_play");
|
||||
}
|
||||
initializedPrefCache = true;
|
||||
}
|
||||
|
||||
class nsAsyncInstantiateEvent : public nsRunnable {
|
||||
public:
|
||||
nsObjectLoadingContent *mContent;
|
||||
@ -181,6 +167,12 @@ nsPluginErrorEvent::Run()
|
||||
case ePluginClickToPlay:
|
||||
type = NS_LITERAL_STRING("PluginClickToPlay");
|
||||
break;
|
||||
case ePluginVulnerableUpdatable:
|
||||
type = NS_LITERAL_STRING("PluginVulnerableUpdatable");
|
||||
break;
|
||||
case ePluginVulnerableNoUpdate:
|
||||
type = NS_LITERAL_STRING("PluginVulnerableNoUpdate");
|
||||
break;
|
||||
case ePluginUnsupported:
|
||||
type = NS_LITERAL_STRING("PluginNotFound");
|
||||
break;
|
||||
@ -484,7 +476,11 @@ nsresult nsObjectLoadingContent::IsPluginEnabledForType(const nsCString& aMIMETy
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (!mShouldPlay) {
|
||||
if (!pluginHost->IsPluginClickToPlayForType(aMIMEType.get())) {
|
||||
mCTPPlayable = true;
|
||||
}
|
||||
|
||||
if (!mCTPPlayable) {
|
||||
nsCOMPtr<nsIContent> thisContent = do_QueryInterface(static_cast<nsIObjectLoadingContent*>(this));
|
||||
MOZ_ASSERT(thisContent);
|
||||
nsIDocument* ownerDoc = thisContent->OwnerDoc();
|
||||
@ -505,12 +501,17 @@ nsresult nsObjectLoadingContent::IsPluginEnabledForType(const nsCString& aMIMETy
|
||||
nsCOMPtr<nsIPermissionManager> permissionManager = do_GetService(NS_PERMISSIONMANAGER_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
PRUint32 permission;
|
||||
rv = permissionManager->TestPermission(topUri,
|
||||
"plugins",
|
||||
&permission);
|
||||
rv = permissionManager->TestPermission(topUri, "plugins", &permission);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (permission == nsIPermissionManager::ALLOW_ACTION) {
|
||||
mShouldPlay = true;
|
||||
|
||||
PRUint32 state;
|
||||
rv = pluginHost->GetBlocklistStateForType(aMIMEType.get(), &state);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (permission == nsIPermissionManager::ALLOW_ACTION &&
|
||||
state != nsIBlocklistService::STATE_VULNERABLE_UPDATE_AVAILABLE &&
|
||||
state != nsIBlocklistService::STATE_VULNERABLE_NO_UPDATE) {
|
||||
mCTPPlayable = true;
|
||||
} else {
|
||||
return NS_ERROR_PLUGIN_CLICKTOPLAY;
|
||||
}
|
||||
@ -542,12 +543,9 @@ GetExtensionFromURI(nsIURI* uri, nsCString& ext)
|
||||
*/
|
||||
bool nsObjectLoadingContent::IsPluginEnabledByExtension(nsIURI* uri, nsCString& mimeType)
|
||||
{
|
||||
if (!mShouldPlay) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCAutoString ext;
|
||||
GetExtensionFromURI(uri, ext);
|
||||
bool enabled = false;
|
||||
|
||||
if (ext.IsEmpty()) {
|
||||
return false;
|
||||
@ -562,9 +560,18 @@ bool nsObjectLoadingContent::IsPluginEnabledByExtension(nsIURI* uri, nsCString&
|
||||
const char* typeFromExt;
|
||||
if (NS_SUCCEEDED(pluginHost->IsPluginEnabledForExtension(ext.get(), typeFromExt))) {
|
||||
mimeType = typeFromExt;
|
||||
return true;
|
||||
enabled = true;
|
||||
|
||||
if (!pluginHost->IsPluginClickToPlayForType(mimeType.get())) {
|
||||
mCTPPlayable = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!mCTPPlayable) {
|
||||
return false;
|
||||
} else {
|
||||
return enabled;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -598,13 +605,8 @@ nsObjectLoadingContent::nsObjectLoadingContent()
|
||||
, mIsStopping(false)
|
||||
, mSrcStreamLoading(false)
|
||||
, mFallbackReason(ePluginOtherState)
|
||||
{
|
||||
InitPrefCache();
|
||||
// If plugins.click_to_play is false, plugins should always play
|
||||
mShouldPlay = !gClickToPlayPlugins;
|
||||
// If plugins.click_to_play is true, track the activated state of plugins.
|
||||
mActivated = !gClickToPlayPlugins;
|
||||
}
|
||||
, mCTPPlayable(false)
|
||||
, mActivated(false) {}
|
||||
|
||||
nsObjectLoadingContent::~nsObjectLoadingContent()
|
||||
{
|
||||
@ -617,10 +619,6 @@ nsObjectLoadingContent::~nsObjectLoadingContent()
|
||||
nsresult
|
||||
nsObjectLoadingContent::InstantiatePluginInstance(const char* aMimeType, nsIURI* aURI)
|
||||
{
|
||||
if (!mShouldPlay) {
|
||||
return NS_ERROR_PLUGIN_CLICKTOPLAY;
|
||||
}
|
||||
|
||||
// Don't do anything if we already have an active instance.
|
||||
if (mInstanceOwner) {
|
||||
return NS_OK;
|
||||
@ -665,6 +663,14 @@ nsObjectLoadingContent::InstantiatePluginInstance(const char* aMimeType, nsIURI*
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (!pluginHost->IsPluginClickToPlayForType(aMimeType)) {
|
||||
mCTPPlayable = true;
|
||||
}
|
||||
|
||||
if (!mCTPPlayable) {
|
||||
return NS_ERROR_PLUGIN_CLICKTOPLAY;
|
||||
}
|
||||
|
||||
// If you add early return(s), be sure to balance this call to
|
||||
// appShell->SuspendNative() with additional call(s) to
|
||||
// appShell->ReturnNative().
|
||||
@ -1191,6 +1197,10 @@ nsObjectLoadingContent::ObjectState() const
|
||||
switch (mFallbackReason) {
|
||||
case ePluginClickToPlay:
|
||||
return NS_EVENT_STATE_TYPE_CLICK_TO_PLAY;
|
||||
case ePluginVulnerableUpdatable:
|
||||
return NS_EVENT_STATE_VULNERABLE_UPDATABLE;
|
||||
case ePluginVulnerableNoUpdate:
|
||||
return NS_EVENT_STATE_VULNERABLE_NO_UPDATE;
|
||||
case ePluginDisabled:
|
||||
state |= NS_EVENT_STATE_HANDLER_DISABLED;
|
||||
break;
|
||||
@ -1933,8 +1943,10 @@ nsObjectLoadingContent::GetPluginSupportState(nsIContent* aContent,
|
||||
}
|
||||
|
||||
PluginSupportState pluginDisabledState = GetPluginDisabledState(aContentType);
|
||||
if (pluginDisabledState == ePluginClickToPlay) {
|
||||
return ePluginClickToPlay;
|
||||
if (pluginDisabledState == ePluginClickToPlay ||
|
||||
pluginDisabledState == ePluginVulnerableUpdatable ||
|
||||
pluginDisabledState == ePluginVulnerableNoUpdate) {
|
||||
return pluginDisabledState;
|
||||
} else if (hasAlternateContent) {
|
||||
return ePluginOtherState;
|
||||
} else {
|
||||
@ -1946,12 +1958,28 @@ PluginSupportState
|
||||
nsObjectLoadingContent::GetPluginDisabledState(const nsCString& aContentType)
|
||||
{
|
||||
nsresult rv = IsPluginEnabledForType(aContentType);
|
||||
if (rv == NS_ERROR_PLUGIN_DISABLED)
|
||||
if (rv == NS_ERROR_PLUGIN_DISABLED) {
|
||||
return ePluginDisabled;
|
||||
if (rv == NS_ERROR_PLUGIN_CLICKTOPLAY)
|
||||
}
|
||||
if (rv == NS_ERROR_PLUGIN_CLICKTOPLAY) {
|
||||
PRUint32 state;
|
||||
nsCOMPtr<nsIPluginHost> pluginHostCOM(do_GetService(MOZ_PLUGIN_HOST_CONTRACTID));
|
||||
nsPluginHost *pluginHost = static_cast<nsPluginHost*>(pluginHostCOM.get());
|
||||
if (pluginHost) {
|
||||
rv = pluginHost->GetBlocklistStateForType(aContentType.get(), &state);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
if (state == nsIBlocklistService::STATE_VULNERABLE_UPDATE_AVAILABLE) {
|
||||
return ePluginVulnerableUpdatable;
|
||||
} else if (state == nsIBlocklistService::STATE_VULNERABLE_NO_UPDATE) {
|
||||
return ePluginVulnerableNoUpdate;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ePluginClickToPlay;
|
||||
if (rv == NS_ERROR_PLUGIN_BLOCKLISTED)
|
||||
}
|
||||
if (rv == NS_ERROR_PLUGIN_BLOCKLISTED) {
|
||||
return ePluginBlocklisted;
|
||||
}
|
||||
return ePluginUnsupported;
|
||||
}
|
||||
|
||||
@ -2213,7 +2241,7 @@ nsObjectLoadingContent::PlayPlugin()
|
||||
if (!nsContentUtils::IsCallerChrome())
|
||||
return NS_OK;
|
||||
|
||||
mShouldPlay = true;
|
||||
mCTPPlayable = true;
|
||||
return LoadObject(mURI, true, mContentType, true);
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,9 @@ enum PluginSupportState {
|
||||
ePluginOutdated, // The plugin is considered outdated, but not disabled
|
||||
ePluginOtherState, // Something else (e.g. uninitialized or not a plugin)
|
||||
ePluginCrashed,
|
||||
ePluginClickToPlay // The plugin is disabled until the user clicks on it
|
||||
ePluginClickToPlay, // The plugin is disabled until the user clicks on it
|
||||
ePluginVulnerableUpdatable, // The plugin is vulnerable (update available)
|
||||
ePluginVulnerableNoUpdate // The plugin is vulnerable (no update available)
|
||||
};
|
||||
|
||||
/**
|
||||
@ -372,9 +374,11 @@ class nsObjectLoadingContent : public nsImageLoadingContent
|
||||
// it may lose the flag.
|
||||
bool mNetworkCreated : 1;
|
||||
|
||||
// Used to keep track of whether or not a plugin should be played.
|
||||
// This is used for click-to-play plugins.
|
||||
bool mShouldPlay : 1;
|
||||
// Used to keep track of if a plugin is blocked by click-to-play.
|
||||
// True indicates the plugin is not click-to-play or it has been clicked by
|
||||
// the user.
|
||||
// False indicates the plugin is click-to-play and has not yet been clicked.
|
||||
bool mCTPPlayable : 1;
|
||||
|
||||
// Used to keep track of whether or not a plugin has been played.
|
||||
// This is used for click-to-play plugins.
|
||||
|
@ -242,6 +242,10 @@ private:
|
||||
#define NS_EVENT_STATE_SUB_OPTIMUM NS_DEFINE_EVENT_STATE_MACRO(38)
|
||||
// Content is in the sub-suboptimal region.
|
||||
#define NS_EVENT_STATE_SUB_SUB_OPTIMUM NS_DEFINE_EVENT_STATE_MACRO(39)
|
||||
// Handler for click to play plugin (vulnerable w/update)
|
||||
#define NS_EVENT_STATE_VULNERABLE_UPDATABLE NS_DEFINE_EVENT_STATE_MACRO(40)
|
||||
// Handler for click to play plugin (vulnerable w/no update)
|
||||
#define NS_EVENT_STATE_VULNERABLE_NO_UPDATE NS_DEFINE_EVENT_STATE_MACRO(41)
|
||||
|
||||
/**
|
||||
* NOTE: do not go over 63 without updating nsEventStates::InternalType!
|
||||
|
@ -282,7 +282,9 @@ nsEventListenerManager::AddEventListener(nsIDOMEventListener *aListener,
|
||||
aTypeAtom == nsGkAtoms::ontouchcancel)) {
|
||||
mMayHaveTouchEventListener = true;
|
||||
nsPIDOMWindow* window = GetInnerWindowForTarget();
|
||||
if (window)
|
||||
// we don't want touchevent listeners added by scrollbars to flip this flag
|
||||
// so we ignore listeners created with system event flag
|
||||
if (window && !(aFlags & NS_EVENT_FLAG_SYSTEM_EVENT))
|
||||
window->SetHasTouchEventListeners();
|
||||
} else if (aTypeAtom == nsGkAtoms::onmouseenter ||
|
||||
aTypeAtom == nsGkAtoms::onmouseleave) {
|
||||
|
@ -1848,12 +1848,6 @@ nsXBLPrototypeBinding::ReadContentNode(nsIObjectInputStream* aStream,
|
||||
|
||||
prototype->mNodeInfo = nodeInfo;
|
||||
|
||||
nsCOMPtr<Element> result;
|
||||
nsresult rv =
|
||||
nsXULElement::Create(prototype, aDocument, false, getter_AddRefs(result));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
content = result;
|
||||
|
||||
nsXULPrototypeAttribute* attrs = nsnull;
|
||||
if (attrCount > 0) {
|
||||
attrs = new nsXULPrototypeAttribute[attrCount];
|
||||
@ -1892,6 +1886,12 @@ nsXBLPrototypeBinding::ReadContentNode(nsIObjectInputStream* aStream,
|
||||
rv = prototype->SetAttrAt(i, val, documentURI);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
nsCOMPtr<Element> result;
|
||||
nsresult rv =
|
||||
nsXULElement::Create(prototype, aDocument, false, getter_AddRefs(result));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
content = result;
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
|
@ -107,6 +107,28 @@ ConsoleAPI.prototype = {
|
||||
timeEnd: function CA_timeEnd() {
|
||||
self.queueCall("timeEnd", arguments);
|
||||
},
|
||||
profile: function CA_profile() {
|
||||
// Send a notification picked up by the profiler if installed.
|
||||
// This must happen right away otherwise we will miss samples
|
||||
let consoleEvent = {
|
||||
action: "profile",
|
||||
arguments: arguments
|
||||
};
|
||||
consoleEvent.wrappedJSObject = consoleEvent;
|
||||
Services.obs.notifyObservers(consoleEvent, "console-api-profiler",
|
||||
null);
|
||||
},
|
||||
profileEnd: function CA_profileEnd() {
|
||||
// Send a notification picked up by the profiler if installed.
|
||||
// This must happen right away otherwise we will miss samples
|
||||
let consoleEvent = {
|
||||
action: "profileEnd",
|
||||
arguments: arguments
|
||||
};
|
||||
consoleEvent.wrappedJSObject = consoleEvent;
|
||||
Services.obs.notifyObservers(consoleEvent, "console-api-profiler",
|
||||
null);
|
||||
},
|
||||
__exposedProps__: {
|
||||
log: "r",
|
||||
info: "r",
|
||||
@ -119,7 +141,9 @@ ConsoleAPI.prototype = {
|
||||
groupCollapsed: "r",
|
||||
groupEnd: "r",
|
||||
time: "r",
|
||||
timeEnd: "r"
|
||||
timeEnd: "r",
|
||||
profile: "r",
|
||||
profileEnd: "r"
|
||||
}
|
||||
};
|
||||
|
||||
@ -143,6 +167,8 @@ ConsoleAPI.prototype = {
|
||||
groupEnd: genPropDesc('groupEnd'),
|
||||
time: genPropDesc('time'),
|
||||
timeEnd: genPropDesc('timeEnd'),
|
||||
profile: genPropDesc('profile'),
|
||||
profileEnd: genPropDesc('profileEnd'),
|
||||
__noSuchMethod__: { enumerable: true, configurable: true, writable: true,
|
||||
value: function() {} },
|
||||
__mozillaConsole__: { value: true }
|
||||
|
@ -21,8 +21,7 @@
|
||||
#define DOM_PROTOTYPE_SLOT (JSCLASS_GLOBAL_SLOT_COUNT + 1)
|
||||
|
||||
// We use these flag bits for the new bindings.
|
||||
#define JSCLASS_IS_DOMJSCLASS JSCLASS_USERBIT1
|
||||
#define JSCLASS_DOM_GLOBAL JSCLASS_USERBIT2
|
||||
#define JSCLASS_DOM_GLOBAL JSCLASS_USERBIT1
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
@ -10,9 +10,8 @@
|
||||
function testSteps()
|
||||
{
|
||||
const name = window.location.pathname;
|
||||
const description = "My Test Database";
|
||||
|
||||
let request = indexedDB.open(name, 1, description);
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = grabEventAndContinueHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
let event = yield;
|
||||
|
@ -51,12 +51,11 @@
|
||||
function testSteps()
|
||||
{
|
||||
const name = window.location.pathname;
|
||||
const description = "My Test Database";
|
||||
|
||||
window.addEventListener("indexedDB-addMore", onAddMore, true);
|
||||
window.addEventListener("indexedDB-done", onDone, true);
|
||||
|
||||
let request = indexedDB.open(name, version++, description);
|
||||
let request = indexedDB.open(name, version++);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
let event = yield;
|
||||
|
@ -13,7 +13,6 @@
|
||||
function testSteps()
|
||||
{
|
||||
const name = window.location.pathname;
|
||||
const description = "My Test Database";
|
||||
const objectStoreInfo = [
|
||||
{ name: "1", options: { keyPath: null } },
|
||||
{ name: "2", options: { keyPath: null, autoIncrement: true } },
|
||||
@ -31,7 +30,7 @@
|
||||
{ name: undefined }
|
||||
];
|
||||
|
||||
let request = indexedDB.open(name, 1, description);
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
let event = yield;
|
||||
|
@ -13,7 +13,6 @@
|
||||
function testSteps()
|
||||
{
|
||||
const name = window.location.pathname;
|
||||
const description = "My Test Database";
|
||||
|
||||
const objectStoreName = "Blobs";
|
||||
|
||||
@ -35,7 +34,7 @@
|
||||
expectedFileIds: [9, 9, 10, 11, 11, 9, 9] }
|
||||
];
|
||||
|
||||
let request = indexedDB.open(name, 1, description);
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
|
@ -15,8 +15,8 @@
|
||||
const READ_WRITE = IDBTransaction.READ_WRITE;
|
||||
|
||||
const databaseInfo = [
|
||||
{ name: window.location.pathname + "1", description: "Test Database 1" },
|
||||
{ name: window.location.pathname + "2", description: "Test Database 2" }
|
||||
{ name: window.location.pathname + "1" },
|
||||
{ name: window.location.pathname + "2" }
|
||||
];
|
||||
|
||||
const objectStoreName = "Blobs";
|
||||
@ -25,7 +25,7 @@
|
||||
|
||||
let databases = [];
|
||||
for each (let info in databaseInfo) {
|
||||
let request = indexedDB.open(info.name, 1, info.description);
|
||||
let request = indexedDB.open(info.name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
|
@ -15,7 +15,6 @@
|
||||
const READ_WRITE = IDBTransaction.READ_WRITE;
|
||||
|
||||
const name = window.location.pathname;
|
||||
const description = "My Test Database";
|
||||
|
||||
const objectStoreName = "Blobs";
|
||||
|
||||
@ -24,7 +23,7 @@
|
||||
const fileData3 = { key: 3, file: getRandomFile("random3.bin", 130000) };
|
||||
|
||||
{
|
||||
let request = indexedDB.open(name, 1, description);
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
@ -67,7 +66,7 @@
|
||||
ok(hasFileInfo(name, 3), "Correct ref count");
|
||||
|
||||
{
|
||||
let request = indexedDB.open(name, 1, description);
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
let event = yield;
|
||||
|
@ -15,7 +15,6 @@
|
||||
const READ_WRITE = IDBTransaction.READ_WRITE;
|
||||
|
||||
const name = window.location.pathname;
|
||||
const description = "My Test Database";
|
||||
|
||||
const objectStoreName = "Blobs";
|
||||
|
||||
@ -25,7 +24,7 @@
|
||||
const fileData = { key: 1, file: getRandomFile("random.bin", 100000) };
|
||||
|
||||
{
|
||||
let request = indexedDB.open(name, 1, description);
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
|
@ -15,7 +15,6 @@
|
||||
const READ_WRITE = IDBTransaction.READ_WRITE;
|
||||
|
||||
const name = window.location.pathname;
|
||||
const description = "My Test Database";
|
||||
|
||||
const objectStoreName = "Blobs";
|
||||
|
||||
@ -25,7 +24,7 @@
|
||||
const objectData1 = { key: 1, object: { foo: blob, bar: blob } };
|
||||
const objectData2 = { key: 2, object: { foo: file, bar: file } };
|
||||
|
||||
let request = indexedDB.open(name, 1, description);
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
|
@ -15,14 +15,13 @@
|
||||
const READ_WRITE = IDBTransaction.READ_WRITE;
|
||||
|
||||
const name = window.location.pathname;
|
||||
const description = "My Test Database";
|
||||
|
||||
const objectStoreName = "Blobs";
|
||||
|
||||
const blobData = { key: 1, blob: getRandomBlob(10000) };
|
||||
const fileData = { key: 2, file: getRandomFile("random.bin", 100000) };
|
||||
|
||||
let request = indexedDB.open(name, 1, description);
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
|
@ -16,14 +16,13 @@
|
||||
const DEFAULT_QUOTA_MB = 50;
|
||||
|
||||
const name = window.location.pathname;
|
||||
const description = "My Test Database";
|
||||
|
||||
const objectStoreName = "Blobs";
|
||||
|
||||
const testData = { key: 0, value: {} };
|
||||
const fileData = { key: 1, file: null };
|
||||
|
||||
let request = indexedDB.open(name, 1, description);
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
|
@ -13,7 +13,6 @@
|
||||
function testSteps()
|
||||
{
|
||||
const name = window.location.pathname;
|
||||
const description = "My Test Database";
|
||||
|
||||
const objectStoreName = "Blobs";
|
||||
|
||||
@ -23,7 +22,7 @@
|
||||
blobData.blobs[i] = getRandomBlob(i);
|
||||
}
|
||||
|
||||
let request = indexedDB.open(name, 1, description);
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
|
@ -15,14 +15,13 @@
|
||||
const READ_WRITE = IDBTransaction.READ_WRITE;
|
||||
|
||||
const name = window.location.pathname;
|
||||
const description = "My Test Database";
|
||||
|
||||
const objectStoreName = "Blobs";
|
||||
|
||||
const fileData = { key: 1, file: getRandomFile("random.bin", 100000) };
|
||||
|
||||
{
|
||||
let request = indexedDB.open(name, 1, description);
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
@ -72,7 +71,7 @@
|
||||
is(getFileRefCount(name, 1), 0, "Correct ref count");
|
||||
|
||||
{
|
||||
let request = indexedDB.open(name, 1, description);
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
let event = yield;
|
||||
|
@ -15,14 +15,13 @@
|
||||
const READ_WRITE = IDBTransaction.READ_WRITE;
|
||||
|
||||
const name = window.location.pathname;
|
||||
const description = "My Test Database";
|
||||
|
||||
const objectStoreName = "Blobs";
|
||||
|
||||
const fileData = { key: 1, file: getRandomFile("random.bin", 100000) };
|
||||
|
||||
{
|
||||
let request = indexedDB.open(name, 1, description);
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
|
@ -15,7 +15,6 @@
|
||||
const READ_WRITE = IDBTransaction.READ_WRITE;
|
||||
|
||||
const name = window.location.pathname;
|
||||
const description = "My Test Database";
|
||||
|
||||
const objectStoreInfo = [
|
||||
{ name: "Blobs", options: { } },
|
||||
@ -24,7 +23,7 @@
|
||||
|
||||
const fileData = { key: 1, file: getRandomFile("random.bin", 100000) };
|
||||
|
||||
let request = indexedDB.open(name, 1, description);
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
|
@ -15,14 +15,13 @@
|
||||
const READ_WRITE = IDBTransaction.READ_WRITE;
|
||||
|
||||
const name = window.location.pathname;
|
||||
const description = "My Test Database";
|
||||
|
||||
const objectStoreName = "Blobs";
|
||||
|
||||
const fileData = { key: 1, file: getRandomFile("random.bin", 100000) };
|
||||
|
||||
{
|
||||
let request = indexedDB.open(name, 1, description);
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
|
@ -16,9 +16,8 @@
|
||||
const DEFAULT_QUOTA_MB = 50;
|
||||
|
||||
const name = window.location.pathname;
|
||||
const description = "My Test Database";
|
||||
|
||||
let request = indexedDB.open(name, 1, description);
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
|
@ -15,8 +15,8 @@
|
||||
const READ_WRITE = IDBTransaction.READ_WRITE;
|
||||
|
||||
const databaseInfo = [
|
||||
{ name: window.location.pathname + "1", description: "Test Database 1" },
|
||||
{ name: window.location.pathname + "2", description: "Test Database 2" }
|
||||
{ name: window.location.pathname + "1" },
|
||||
{ name: window.location.pathname + "2" }
|
||||
];
|
||||
|
||||
const objectStoreName = "Blobs";
|
||||
@ -25,7 +25,7 @@
|
||||
|
||||
let databases = [];
|
||||
for each (let info in databaseInfo) {
|
||||
let request = indexedDB.open(info.name, 1, info.description);
|
||||
let request = indexedDB.open(info.name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
|
@ -15,13 +15,12 @@
|
||||
const READ_WRITE = IDBTransaction.READ_WRITE;
|
||||
|
||||
const name = window.location.pathname;
|
||||
const description = "My Test Database";
|
||||
|
||||
const objectStoreName = "Blobs";
|
||||
|
||||
const testFile = getRandomFile("random.bin", 100000);
|
||||
|
||||
let request = indexedDB.open(name, 1, description);
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
|
@ -13,10 +13,9 @@
|
||||
function testSteps()
|
||||
{
|
||||
const name = window.location.pathname;
|
||||
const description = "My Test Database";
|
||||
const osName = "foo";
|
||||
|
||||
let request = indexedDB.open(name, 1, description);
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
|
@ -8,9 +8,8 @@ var testGenerator = testSteps();
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
const description = "My Test Database";
|
||||
|
||||
let request = indexedDB.open(name, 1, description);
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
let event = yield;
|
||||
|
@ -8,10 +8,9 @@ var testGenerator = testSteps();
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
const description = "My Test Database";
|
||||
const entryCount = 1000;
|
||||
|
||||
let request = indexedDB.open(name, 1, description);
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
let event = yield;
|
||||
|
@ -8,7 +8,6 @@ var testGenerator = testSteps();
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
const description = "My Test Database";
|
||||
const START_DATA = "hi";
|
||||
const END_DATA = "bye";
|
||||
const objectStoreInfo = [
|
||||
@ -27,7 +26,7 @@ function testSteps()
|
||||
let info = objectStoreInfo[i];
|
||||
|
||||
ok(true, "1");
|
||||
request = indexedDB.open(name, i + 1, description);
|
||||
request = indexedDB.open(name, i + 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
event = yield;
|
||||
|
@ -8,13 +8,12 @@ var testGenerator = testSteps();
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
const description = "My Test Database";
|
||||
const keys = [1, -1, 0, 10, 2000, "q", "z", "two", "b", "a"];
|
||||
const sortedKeys = [-1, 0, 1, 10, 2000, "a", "b", "q", "two", "z"];
|
||||
|
||||
is(keys.length, sortedKeys.length, "Good key setup");
|
||||
|
||||
let request = indexedDB.open(name, 1, description);
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
let event = yield;
|
||||
|
@ -8,10 +8,9 @@ var testGenerator = testSteps();
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
const description = "My Test Database";
|
||||
const objectStoreName = "Objects";
|
||||
|
||||
var request = indexedDB.open(name, 1, description);
|
||||
var request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
var event = yield;
|
||||
|
@ -8,11 +8,10 @@ var testGenerator = testSteps();
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
const description = "My Test Database";
|
||||
|
||||
const values = [ "a", "1", 1, "foo", 300, true, false, 4.5, null ];
|
||||
|
||||
let request = indexedDB.open(name, 1, description);
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
let event = yield;
|
||||
|
@ -8,11 +8,10 @@ var testGenerator = testSteps();
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
const description = "My Test Database";
|
||||
const objectStore = { name: "Objects",
|
||||
options: { keyPath: "id", autoIncrement: true } };
|
||||
|
||||
let request = indexedDB.open(name, 1, description);
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
let event = yield;
|
||||
@ -26,7 +25,7 @@ function testSteps()
|
||||
continueToNextStep();
|
||||
yield;
|
||||
|
||||
request = indexedDB.open(name, 1, description);
|
||||
request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield;
|
||||
|
@ -8,7 +8,6 @@ var testGenerator = testSteps();
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
const description = "My Test Database";
|
||||
const objectStoreName = "People";
|
||||
|
||||
const objectStoreData = [
|
||||
@ -52,7 +51,7 @@ function testSteps()
|
||||
{ key: "237-23-7734", value: { name: "Ron", height: 73, weight: 180 } }
|
||||
];
|
||||
|
||||
let request = indexedDB.open(name, 1, description);
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
|
@ -8,7 +8,6 @@ var testGenerator = testSteps();
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
const description = "My Test Database";
|
||||
const objectStoreName = "People";
|
||||
|
||||
const objectStoreData = [
|
||||
@ -52,7 +51,7 @@ function testSteps()
|
||||
{ key: "237-23-7734", value: { name: "Ron", height: 73, weight: 180 } }
|
||||
];
|
||||
|
||||
let request = indexedDB.open(name, 1, description);
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
|
@ -8,7 +8,6 @@ var testGenerator = testSteps();
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? this.window ? window.location.pathname : "Splendid Test" : "Splendid Test";
|
||||
const description = "My Test Database";
|
||||
|
||||
const objectStoreName = "People";
|
||||
|
||||
@ -53,7 +52,7 @@ function testSteps()
|
||||
{ key: "237-23-7734", value: { name: "Ron", height: 73, weight: 180 } }
|
||||
];
|
||||
|
||||
let request = indexedDB.open(name, 1, description);
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
|
@ -8,7 +8,6 @@ var testGenerator = testSteps();
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
const description = "My Test Database";
|
||||
|
||||
const objectStoreName = "People";
|
||||
|
||||
@ -39,7 +38,7 @@ function testSteps()
|
||||
{ key: "237-23-7734", value: { name: "Ron", height: 73, weight: 180 } }
|
||||
];
|
||||
|
||||
let request = indexedDB.open(name, 1, description);
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
|
@ -8,9 +8,8 @@ var testGenerator = testSteps();
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
const description = "My Test Database";
|
||||
|
||||
let request = indexedDB.open(name, 1, description);
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
let event = yield;
|
||||
|
@ -8,7 +8,6 @@ var testGenerator = testSteps();
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
const description = "My Test Database";
|
||||
|
||||
const objectStores = [
|
||||
{ name: "a", autoIncrement: false },
|
||||
@ -22,7 +21,7 @@ function testSteps()
|
||||
|
||||
var j = 0;
|
||||
for (let i in objectStores) {
|
||||
let request = indexedDB.open(name, ++j, description);
|
||||
let request = indexedDB.open(name, ++j);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
let event = yield;
|
||||
@ -55,7 +54,7 @@ function testSteps()
|
||||
executeSoon(function() { testGenerator.next(); });
|
||||
yield;
|
||||
|
||||
let request = indexedDB.open(name, j, description);
|
||||
let request = indexedDB.open(name, j);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
let event = yield;
|
||||
|
@ -9,9 +9,8 @@ function testSteps()
|
||||
{
|
||||
const IDBObjectStore = Components.interfaces.nsIIDBObjectStore;
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
const description = "My Test Database";
|
||||
|
||||
var request = indexedDB.open(name, 1, description);
|
||||
var request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
var event = yield;
|
||||
|
@ -9,7 +9,6 @@ function testSteps()
|
||||
{
|
||||
const IDBObjectStore = Components.interfaces.nsIIDBObjectStore;
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
const description = "My Test Database";
|
||||
|
||||
var data = [
|
||||
{ name: "inline key; key generator",
|
||||
@ -41,7 +40,7 @@ function testSteps()
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
let test = data[i];
|
||||
|
||||
let request = indexedDB.open(name, i+1, description);
|
||||
let request = indexedDB.open(name, i+1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
let event = yield;
|
||||
|
@ -9,10 +9,9 @@ function testSteps()
|
||||
{
|
||||
const nsIIDBObjectStore = Components.interfaces.nsIIDBObjectStore;
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
const description = "My Test Database";
|
||||
const objectStoreName = "Objects";
|
||||
|
||||
let request = indexedDB.open(name, 1, description);
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
|
@ -8,10 +8,9 @@ var testGenerator = testSteps();
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
const description = "My Test Database";
|
||||
const objectStores = [ "foo", "bar" ];
|
||||
|
||||
let request = indexedDB.open(name, 1, description);
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
let event = yield;
|
||||
|
@ -8,13 +8,12 @@ var testGenerator = testSteps();
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
const description = "My Test Database";
|
||||
const objectStoreName = "Objects";
|
||||
|
||||
let testString = { key: 0, value: "testString" };
|
||||
let testInt = { key: 1, value: 1002 };
|
||||
|
||||
let request = indexedDB.open(name, 1, description);
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
let event = yield;
|
||||
|
@ -8,13 +8,12 @@ var testGenerator = testSteps();
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
const description = "My Test Database";
|
||||
const objectStoreName = "Objects";
|
||||
|
||||
let testString = { value: "testString" };
|
||||
let testInt = { value: 1002 };
|
||||
|
||||
let request = indexedDB.open(name, 1, description);
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
let event = yield;
|
||||
|
@ -10,10 +10,9 @@ function testSteps()
|
||||
const nsIIDBObjectStore = Components.interfaces.nsIIDBObjectStore;
|
||||
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
const description = "My Test Database";
|
||||
const indexName = "My Test Index";
|
||||
|
||||
let request = indexedDB.open(name, 1, description);
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
let event = yield;
|
||||
|
@ -10,10 +10,9 @@ function testSteps()
|
||||
const nsIIDBObjectStore = Components.interfaces.nsIIDBObjectStore;
|
||||
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
const description = "My Test Database";
|
||||
const objectStoreName = "Objects";
|
||||
|
||||
let request = indexedDB.open(name, 1, description);
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
let event = yield;
|
||||
@ -42,7 +41,7 @@ function testSteps()
|
||||
|
||||
db.close();
|
||||
|
||||
let request = indexedDB.open(name, 2, description);
|
||||
let request = indexedDB.open(name, 2);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
let event = yield;
|
||||
@ -86,7 +85,7 @@ function testSteps()
|
||||
|
||||
db.close();
|
||||
|
||||
let request = indexedDB.open(name, 3, description);
|
||||
let request = indexedDB.open(name, 3);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
let event = yield;
|
||||
|
@ -8,9 +8,8 @@ var testGenerator = testSteps();
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
const description = "My Test Database";
|
||||
|
||||
let request = indexedDB.open(name, 1, description);
|
||||
let request = indexedDB.open(name, 1);
|
||||
is(request.readyState, "pending", "Correct readyState");
|
||||
|
||||
request.onerror = errorHandler;
|
||||
|
@ -8,9 +8,8 @@ var testGenerator = testSteps();
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
const description = "My Test Database";
|
||||
|
||||
let request = indexedDB.open(name, 1, description);
|
||||
let request = indexedDB.open(name, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
let event = yield;
|
||||
@ -30,7 +29,7 @@ function testSteps()
|
||||
for (let i = 0; i < versions.length; i++) {
|
||||
let version = versions[i];
|
||||
|
||||
let request = indexedDB.open(name, version, description);
|
||||
let request = indexedDB.open(name, version);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
let event = yield;
|
||||
|
@ -8,10 +8,9 @@ var testGenerator = testSteps();
|
||||
function testSteps()
|
||||
{
|
||||
const name = this.window ? window.location.pathname : "Splendid Test";
|
||||
const description = "My Test Database";
|
||||
|
||||
// Open a datbase for the first time.
|
||||
let request = indexedDB.open(name, 1, description);
|
||||
let request = indexedDB.open(name, 1);
|
||||
|
||||
// Sanity checks
|
||||
ok(request instanceof IDBRequest, "Request should be an IDBRequest");
|
||||
@ -46,7 +45,7 @@ function testSteps()
|
||||
}, false);
|
||||
|
||||
// Open the database again and trigger an upgrade that should succeed
|
||||
request = indexedDB.open(name, 2, description);
|
||||
request = indexedDB.open(name, 2);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
@ -84,7 +83,7 @@ function testSteps()
|
||||
}, false);
|
||||
|
||||
// Test opening the existing version again
|
||||
request = indexedDB.open(name, 2, description);
|
||||
request = indexedDB.open(name, 2);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
if (SpecialPowers.isMainProcess()) {
|
||||
@ -98,7 +97,7 @@ function testSteps()
|
||||
db3 = event.target.result;
|
||||
|
||||
// Test an upgrade that should fail
|
||||
request = indexedDB.open(name, 3, description);
|
||||
request = indexedDB.open(name, 3);
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = errorHandler;
|
||||
request.onupgradeneeded = errorHandler;
|
||||
|
@ -98,6 +98,15 @@ CrashReporterParent::GenerateHangCrashReport(const AnnotationTable* processNotes
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CrashReporterParent::GenerateCrashReportForMinidump(nsIFile* minidump,
|
||||
const AnnotationTable* processNotes)
|
||||
{
|
||||
if (!CrashReporter::GetIDFromMinidump(minidump, mChildDumpID))
|
||||
return false;
|
||||
return GenerateChildData(processNotes);
|
||||
}
|
||||
|
||||
bool
|
||||
CrashReporterParent::GenerateChildData(const AnnotationTable* processNotes)
|
||||
{
|
||||
|
@ -49,6 +49,10 @@ public:
|
||||
bool
|
||||
GenerateCrashReport(Toplevel* t, const AnnotationTable* processNotes);
|
||||
|
||||
bool
|
||||
GenerateCrashReportForMinidump(nsIFile* minidump,
|
||||
const AnnotationTable* processNotes);
|
||||
|
||||
/* Instantiate a new crash reporter actor from a given parent that manages
|
||||
the protocol.
|
||||
*/
|
||||
@ -135,7 +139,7 @@ CrashReporterParent::GenerateCrashReport(Toplevel* t,
|
||||
const AnnotationTable* processNotes)
|
||||
{
|
||||
nsCOMPtr<nsIFile> crashDump;
|
||||
if (t->TakeMinidump(getter_AddRefs(crashDump)) &&
|
||||
if (t->TakeMinidump(getter_AddRefs(crashDump), NULL) &&
|
||||
CrashReporter::GetIDFromMinidump(crashDump, mChildDumpID)) {
|
||||
return GenerateChildData(processNotes);
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
[scriptable, uuid(88e03453-a773-47ba-9d84-14f672ac99e2)]
|
||||
[scriptable, uuid(a361a7e7-7f8d-4b68-91e9-30ae096460d4)]
|
||||
interface nsIPluginTag : nsISupports
|
||||
{
|
||||
readonly attribute AUTF8String description;
|
||||
@ -15,4 +15,5 @@ interface nsIPluginTag : nsISupports
|
||||
readonly attribute AUTF8String name;
|
||||
attribute boolean disabled;
|
||||
attribute boolean blocklisted;
|
||||
attribute boolean clicktoplay;
|
||||
};
|
||||
|
@ -342,8 +342,10 @@ nsPluginHost::nsPluginHost()
|
||||
Preferences::GetBool("plugin.override_internal_types", false);
|
||||
|
||||
mPluginsDisabled = Preferences::GetBool("plugin.disable", false);
|
||||
mPluginsClickToPlay = Preferences::GetBool("plugins.click_to_play", false);
|
||||
|
||||
Preferences::AddStrongObserver(this, "plugin.disable");
|
||||
Preferences::AddStrongObserver(this, "plugins.click_to_play");
|
||||
|
||||
nsCOMPtr<nsIObserverService> obsService =
|
||||
mozilla::services::GetObserverService();
|
||||
@ -1294,6 +1296,36 @@ nsPluginHost::IsPluginEnabledForType(const char* aMimeType)
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
nsPluginHost::IsPluginClickToPlayForType(const char* aMimeType)
|
||||
{
|
||||
nsPluginTag *plugin = FindPluginForType(aMimeType, true);
|
||||
if (plugin &&
|
||||
(plugin->HasFlag(NS_PLUGIN_FLAG_CLICKTOPLAY) || mPluginsClickToPlay)) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsPluginHost::GetBlocklistStateForType(const char *aMimeType, PRUint32 *aState)
|
||||
{
|
||||
nsPluginTag *plugin = FindPluginForType(aMimeType, true);
|
||||
if (plugin) {
|
||||
nsCOMPtr<nsIBlocklistService> blocklist = do_GetService("@mozilla.org/extensions/blocklist;1");
|
||||
if (blocklist) {
|
||||
// The EmptyString()s are so we use the currently running application
|
||||
// and toolkit versions
|
||||
return blocklist->GetPluginBlocklistState(plugin, EmptyString(),
|
||||
EmptyString(), aState);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// check comma delimitered extensions
|
||||
static int CompareExtensions(const char *aExtensionList, const char *aExtension)
|
||||
@ -2074,19 +2106,32 @@ nsresult nsPluginHost::ScanPluginsDirectory(nsIFile *pluginsDir,
|
||||
EmptyString(), &state);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// If the blocklist says so then block the plugin. If the blocklist says
|
||||
// it is risky and we have never seen this plugin before then disable it
|
||||
if (state == nsIBlocklistService::STATE_BLOCKED)
|
||||
pluginTag->Mark(NS_PLUGIN_FLAG_BLOCKLISTED);
|
||||
else if (state == nsIBlocklistService::STATE_SOFTBLOCKED && !seenBefore)
|
||||
enabled = false;
|
||||
else if (state == nsIBlocklistService::STATE_OUTDATED && !seenBefore)
|
||||
warnOutdated = true;
|
||||
// If the blocklist says so, block the plugin.
|
||||
// If the blocklist says it is risky and we have never seen this
|
||||
// plugin before, then disable it.
|
||||
// If the blocklist says this is an outdated plugin, warn about
|
||||
// outdated plugins.
|
||||
// If the blocklist says the plugin is one of the click-to-play
|
||||
// states, set the click-to-play flag.
|
||||
if (state == nsIBlocklistService::STATE_BLOCKED) {
|
||||
pluginTag->Mark(NS_PLUGIN_FLAG_BLOCKLISTED);
|
||||
}
|
||||
if (state == nsIBlocklistService::STATE_SOFTBLOCKED && !seenBefore) {
|
||||
enabled = false;
|
||||
}
|
||||
if (state == nsIBlocklistService::STATE_OUTDATED && !seenBefore) {
|
||||
warnOutdated = true;
|
||||
}
|
||||
if (state == nsIBlocklistService::STATE_VULNERABLE_UPDATE_AVAILABLE ||
|
||||
state == nsIBlocklistService::STATE_VULNERABLE_NO_UPDATE) {
|
||||
pluginTag->Mark(NS_PLUGIN_FLAG_CLICKTOPLAY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!enabled)
|
||||
if (!enabled) {
|
||||
pluginTag->UnMark(NS_PLUGIN_FLAG_ENABLED);
|
||||
}
|
||||
|
||||
// Plugin unloading is tag-based. If we created a new tag and loaded
|
||||
// the library in the process then we want to attempt to unload it here.
|
||||
@ -3302,6 +3347,7 @@ NS_IMETHODIMP nsPluginHost::Observe(nsISupports *aSubject,
|
||||
}
|
||||
if (!nsCRT::strcmp(NS_PREFBRANCH_PREFCHANGE_TOPIC_ID, aTopic)) {
|
||||
mPluginsDisabled = Preferences::GetBool("plugin.disable", false);
|
||||
mPluginsClickToPlay = Preferences::GetBool("plugins.click_to_play", false);
|
||||
// Unload or load plugins as needed
|
||||
if (mPluginsDisabled) {
|
||||
UnloadPlugins();
|
||||
|
@ -85,6 +85,8 @@ public:
|
||||
nsIPluginInstanceOwner *aOwner);
|
||||
nsresult IsPluginEnabledForType(const char* aMimeType);
|
||||
nsresult IsPluginEnabledForExtension(const char* aExtension, const char* &aMimeType);
|
||||
bool IsPluginClickToPlayForType(const char *aMimeType);
|
||||
nsresult GetBlocklistStateForType(const char *aMimeType, PRUint32 *state);
|
||||
|
||||
nsresult GetPluginCount(PRUint32* aPluginCount);
|
||||
nsresult GetPlugins(PRUint32 aPluginCount, nsIDOMPlugin** aPluginArray);
|
||||
@ -281,6 +283,8 @@ private:
|
||||
|
||||
// set by pref plugin.disable
|
||||
bool mPluginsDisabled;
|
||||
// set by pref plugins.click_to_play
|
||||
bool mPluginsClickToPlay;
|
||||
|
||||
// Any instances in this array will have valid plugin objects via GetPlugin().
|
||||
// When removing an instance it might not die - be sure to null out it's plugin.
|
||||
|
@ -320,6 +320,30 @@ nsPluginTag::SetBlocklisted(bool aBlocklisted)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPluginTag::GetClicktoplay(bool *aClicktoplay)
|
||||
{
|
||||
*aClicktoplay = HasFlag(NS_PLUGIN_FLAG_CLICKTOPLAY);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPluginTag::SetClicktoplay(bool aClicktoplay)
|
||||
{
|
||||
if (HasFlag(NS_PLUGIN_FLAG_CLICKTOPLAY) == aClicktoplay) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (aClicktoplay) {
|
||||
Mark(NS_PLUGIN_FLAG_CLICKTOPLAY);
|
||||
} else {
|
||||
UnMark(NS_PLUGIN_FLAG_CLICKTOPLAY);
|
||||
}
|
||||
|
||||
mPluginHost->UpdatePluginInfo(nsnull);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsPluginTag::Mark(PRUint32 mask)
|
||||
{
|
||||
bool wasEnabled = IsEnabled();
|
||||
|
@ -27,6 +27,7 @@ struct nsPluginInfo;
|
||||
#define NS_PLUGIN_FLAG_FROMCACHE 0x0004 // this plugintag info was loaded from cache
|
||||
// no longer used 0x0008 // reuse only if regenerating pluginreg.dat
|
||||
#define NS_PLUGIN_FLAG_BLOCKLISTED 0x0010 // this is a blocklisted plugin
|
||||
#define NS_PLUGIN_FLAG_CLICKTOPLAY 0x0020 // this is a click-to-play plugin
|
||||
|
||||
// A linked-list of plugin information that is used for instantiating plugins
|
||||
// and reflecting plugin information into JavaScript.
|
||||
|
@ -27,9 +27,6 @@
|
||||
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsCRT.h"
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
#include "mozilla/dom/CrashReporterParent.h"
|
||||
#endif
|
||||
#include "nsNPAPIPlugin.h"
|
||||
#include "nsIFile.h"
|
||||
|
||||
@ -49,6 +46,12 @@ using namespace mozilla;
|
||||
using namespace mozilla::plugins;
|
||||
using namespace mozilla::plugins::parent;
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
#include "mozilla/dom/CrashReporterParent.h"
|
||||
|
||||
using namespace CrashReporter;
|
||||
#endif
|
||||
|
||||
static const char kChildTimeoutPref[] = "dom.ipc.plugins.timeoutSecs";
|
||||
static const char kParentTimeoutPref[] = "dom.ipc.plugins.parentTimeoutSecs";
|
||||
static const char kLaunchTimeoutPref[] = "dom.ipc.plugins.processLaunchTimeoutSecs";
|
||||
@ -133,9 +136,9 @@ PluginModuleParent::~PluginModuleParent()
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER_INJECTOR
|
||||
if (mFlashProcess1)
|
||||
CrashReporter::UnregisterInjectorCallback(mFlashProcess1);
|
||||
UnregisterInjectorCallback(mFlashProcess1);
|
||||
if (mFlashProcess2)
|
||||
CrashReporter::UnregisterInjectorCallback(mFlashProcess2);
|
||||
UnregisterInjectorCallback(mFlashProcess2);
|
||||
#endif
|
||||
|
||||
Preferences::UnregisterCallback(TimeoutChanged, kChildTimeoutPref, this);
|
||||
@ -144,7 +147,7 @@ PluginModuleParent::~PluginModuleParent()
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
void
|
||||
PluginModuleParent::WriteExtraDataForMinidump(CrashReporter::AnnotationTable& notes)
|
||||
PluginModuleParent::WriteExtraDataForMinidump(AnnotationTable& notes)
|
||||
{
|
||||
typedef nsDependentCString CS;
|
||||
|
||||
@ -200,19 +203,17 @@ bool
|
||||
PluginModuleParent::ShouldContinueFromReplyTimeout()
|
||||
{
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
if (mPluginDumpID.IsEmpty()) {
|
||||
CrashReporterParent* crashReporter = CrashReporter();
|
||||
if (crashReporter->GeneratePairedMinidump(this)) {
|
||||
mBrowserDumpID = crashReporter->ParentDumpID();
|
||||
mPluginDumpID = crashReporter->ChildDumpID();
|
||||
PLUGIN_LOG_DEBUG(
|
||||
("generated paired browser/plugin minidumps: %s/%s (ID=%s)",
|
||||
NS_ConvertUTF16toUTF8(mBrowserDumpID).get(),
|
||||
NS_ConvertUTF16toUTF8(mPluginDumpID).get(),
|
||||
NS_ConvertUTF16toUTF8(crashReporter->HangID()).get()));
|
||||
} else {
|
||||
NS_WARNING("failed to capture paired minidumps from hang");
|
||||
}
|
||||
CrashReporterParent* crashReporter = CrashReporter();
|
||||
if (crashReporter->GeneratePairedMinidump(this)) {
|
||||
mBrowserDumpID = crashReporter->ParentDumpID();
|
||||
mPluginDumpID = crashReporter->ChildDumpID();
|
||||
PLUGIN_LOG_DEBUG(
|
||||
("generated paired browser/plugin minidumps: %s/%s (ID=%s)",
|
||||
NS_ConvertUTF16toUTF8(mBrowserDumpID).get(),
|
||||
NS_ConvertUTF16toUTF8(mPluginDumpID).get(),
|
||||
NS_ConvertUTF16toUTF8(crashReporter->HangID()).get()));
|
||||
} else {
|
||||
NS_WARNING("failed to capture paired minidumps from hang");
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -237,33 +238,99 @@ PluginModuleParent::CrashReporter()
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
static void
|
||||
RemoveMinidump(nsIFile* minidump)
|
||||
{
|
||||
if (!minidump)
|
||||
return;
|
||||
|
||||
minidump->Remove(false);
|
||||
nsCOMPtr<nsIFile> extraFile;
|
||||
if (GetExtraFileForMinidump(minidump,
|
||||
getter_AddRefs(extraFile))) {
|
||||
extraFile->Remove(true);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PluginModuleParent::ProcessFirstMinidump()
|
||||
{
|
||||
CrashReporterParent* crashReporter = CrashReporter();
|
||||
if (!crashReporter)
|
||||
return;
|
||||
|
||||
AnnotationTable notes;
|
||||
notes.Init(4);
|
||||
WriteExtraDataForMinidump(notes);
|
||||
|
||||
if (!mPluginDumpID.IsEmpty() && !mBrowserDumpID.IsEmpty()) {
|
||||
crashReporter->GenerateHangCrashReport(¬es);
|
||||
return;
|
||||
}
|
||||
|
||||
PRUint32 sequence = PR_UINT32_MAX;
|
||||
nsCOMPtr<nsIFile> dumpFile;
|
||||
nsCAutoString flashProcessType;
|
||||
TakeMinidump(getter_AddRefs(dumpFile), &sequence);
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER_INJECTOR
|
||||
nsCOMPtr<nsIFile> childDumpFile;
|
||||
PRUint32 childSequence;
|
||||
|
||||
if (mFlashProcess1 &&
|
||||
TakeMinidumpForChild(mFlashProcess1,
|
||||
getter_AddRefs(childDumpFile),
|
||||
&childSequence)) {
|
||||
if (childSequence < sequence) {
|
||||
RemoveMinidump(dumpFile);
|
||||
dumpFile = childDumpFile;
|
||||
sequence = childSequence;
|
||||
flashProcessType.AssignLiteral("Broker");
|
||||
}
|
||||
else {
|
||||
RemoveMinidump(childDumpFile);
|
||||
}
|
||||
}
|
||||
if (mFlashProcess2 &&
|
||||
TakeMinidumpForChild(mFlashProcess2,
|
||||
getter_AddRefs(childDumpFile),
|
||||
&childSequence)) {
|
||||
if (childSequence < sequence) {
|
||||
RemoveMinidump(dumpFile);
|
||||
dumpFile = childDumpFile;
|
||||
sequence = childSequence;
|
||||
flashProcessType.AssignLiteral("Sandbox");
|
||||
}
|
||||
else {
|
||||
RemoveMinidump(childDumpFile);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!dumpFile) {
|
||||
NS_WARNING("[PluginModuleParent::ActorDestroy] abnormal shutdown without minidump!");
|
||||
return;
|
||||
}
|
||||
|
||||
PLUGIN_LOG_DEBUG(("got child minidump: %s",
|
||||
NS_ConvertUTF16toUTF8(mPluginDumpID).get()));
|
||||
|
||||
GetIDFromMinidump(dumpFile, mPluginDumpID);
|
||||
if (!flashProcessType.IsEmpty()) {
|
||||
notes.Put(NS_LITERAL_CSTRING("FlashProcessDump"), flashProcessType);
|
||||
}
|
||||
crashReporter->GenerateCrashReportForMinidump(dumpFile, ¬es);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
PluginModuleParent::ActorDestroy(ActorDestroyReason why)
|
||||
{
|
||||
switch (why) {
|
||||
case AbnormalShutdown: {
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
CrashReporterParent* crashReporter = CrashReporter();
|
||||
|
||||
CrashReporter::AnnotationTable notes;
|
||||
notes.Init(4);
|
||||
WriteExtraDataForMinidump(notes);
|
||||
|
||||
if (!mPluginDumpID.IsEmpty() && !mBrowserDumpID.IsEmpty()) {
|
||||
crashReporter->GenerateHangCrashReport(¬es);
|
||||
}
|
||||
else if (!mPluginDumpID.IsEmpty()) {
|
||||
// Nothing to do, we've already written this minidump in
|
||||
// PluginModuleParent::OnCrash
|
||||
}
|
||||
else if (crashReporter->GenerateCrashReport(this, ¬es)) {
|
||||
mPluginDumpID = crashReporter->ChildDumpID();
|
||||
PLUGIN_LOG_DEBUG(("got child minidump: %s",
|
||||
NS_ConvertUTF16toUTF8(mPluginDumpID).get()));
|
||||
}
|
||||
else {
|
||||
NS_WARNING("[PluginModuleParent::ActorDestroy] abnormal shutdown without minidump!");
|
||||
}
|
||||
ProcessFirstMinidump();
|
||||
#endif
|
||||
|
||||
mShutdown = true;
|
||||
@ -1248,33 +1315,8 @@ PluginModuleParent::InitializeInjector()
|
||||
}
|
||||
|
||||
void
|
||||
PluginModuleParent::OnCrash(DWORD processID, const nsAString& aDumpID)
|
||||
PluginModuleParent::OnCrash(DWORD processID)
|
||||
{
|
||||
if (!mPluginDumpID.IsEmpty()) {
|
||||
// One process has already crashed: we assume that the first-to-crash
|
||||
// is the interesting one
|
||||
return;
|
||||
}
|
||||
|
||||
mPluginDumpID = aDumpID;
|
||||
|
||||
CrashReporter::AnnotationTable notes;
|
||||
notes.Init(4);
|
||||
WriteExtraDataForMinidump(notes);
|
||||
notes.Put(NS_LITERAL_CSTRING("ProcessType"), NS_LITERAL_CSTRING("plugin"));
|
||||
if (processID == mFlashProcess1) {
|
||||
notes.Put(NS_LITERAL_CSTRING("FlashProcessDump"),
|
||||
NS_LITERAL_CSTRING("Broker"));
|
||||
}
|
||||
else if (processID == mFlashProcess2) {
|
||||
notes.Put(NS_LITERAL_CSTRING("FlashProcessDump"),
|
||||
NS_LITERAL_CSTRING("Sandbox"));
|
||||
}
|
||||
else {
|
||||
NS_ERROR("Got minidump for Flash process neither broker nor sandbox.");
|
||||
}
|
||||
CrashReporter::AppendExtraData(aDumpID, notes);
|
||||
|
||||
GetIPCChannel()->CloseWithError();
|
||||
KillProcess(OtherProcess(), 1, false);
|
||||
}
|
||||
|
@ -288,6 +288,7 @@ private:
|
||||
CrashReporterParent* CrashReporter();
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
void ProcessFirstMinidump();
|
||||
void WriteExtraDataForMinidump(CrashReporter::AnnotationTable& notes);
|
||||
#endif
|
||||
void CleanupFromTimeout();
|
||||
@ -319,7 +320,7 @@ private:
|
||||
#ifdef MOZ_CRASHREPORTER_INJECTOR
|
||||
void InitializeInjector();
|
||||
|
||||
NS_OVERRIDE void OnCrash(DWORD processID, const nsAString& aDumpID);
|
||||
NS_OVERRIDE void OnCrash(DWORD processID);
|
||||
|
||||
DWORD mFlashProcess1;
|
||||
DWORD mFlashProcess2;
|
||||
|
@ -32,6 +32,8 @@ function doTest() {
|
||||
"groupEnd": "function",
|
||||
"time": "function",
|
||||
"timeEnd": "function",
|
||||
"profile": "function",
|
||||
"profileEnd": "function",
|
||||
"__noSuchMethod__": "function"
|
||||
};
|
||||
|
||||
|
@ -236,9 +236,14 @@ var WifiManager = (function() {
|
||||
|
||||
function scanCommand(forceActive, callback) {
|
||||
if (forceActive && !scanModeActive) {
|
||||
doSetScanModeCommand(true, function(ok) {
|
||||
ok && doBooleanCommand("SCAN", "OK", function(ok) {
|
||||
ok && doSetScanModeCommand(false, callback);
|
||||
// Note: we ignore errors from doSetScanMode.
|
||||
doSetScanModeCommand(true, function(ignore) {
|
||||
doBooleanCommand("SCAN", "OK", function(ok) {
|
||||
doSetScanModeCommand(false, function(ignore) {
|
||||
// The result of scanCommand is the result of the actual SCAN
|
||||
// request.
|
||||
callback(ok);
|
||||
});
|
||||
});
|
||||
});
|
||||
return;
|
||||
@ -603,7 +608,7 @@ var WifiManager = (function() {
|
||||
}
|
||||
|
||||
manager.start = function() {
|
||||
debug("detected SDK version " + sdkVersion);
|
||||
debug("detected SDK version " + sdkVersion + " and device " + device);
|
||||
|
||||
// If we reconnected to an already-running supplicant, then manager.state
|
||||
// will have already been updated to the supplicant's state. Otherwise, we
|
||||
|
@ -29,13 +29,13 @@ nsSelectionState::DoTraverse(nsCycleCollectionTraversalCallback &cb)
|
||||
{
|
||||
for (PRUint32 i = 0, iEnd = mArray.Length(); i < iEnd; ++i)
|
||||
{
|
||||
nsRangeStore &item = mArray[i];
|
||||
nsRangeStore* item = mArray[i];
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb,
|
||||
"selection state mArray[i].startNode");
|
||||
cb.NoteXPCOMChild(item.startNode);
|
||||
cb.NoteXPCOMChild(item->startNode);
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb,
|
||||
"selection state mArray[i].endNode");
|
||||
cb.NoteXPCOMChild(item.endNode);
|
||||
cb.NoteXPCOMChild(item->endNode);
|
||||
}
|
||||
}
|
||||
|
||||
@ -53,6 +53,7 @@ nsSelectionState::SaveSelection(nsISelection *aSel)
|
||||
for (i=0; i<count; i++)
|
||||
{
|
||||
mArray.AppendElement();
|
||||
mArray[i] = new nsRangeStore();
|
||||
}
|
||||
}
|
||||
|
||||
@ -71,7 +72,7 @@ nsSelectionState::SaveSelection(nsISelection *aSel)
|
||||
{
|
||||
nsCOMPtr<nsIDOMRange> range;
|
||||
res = aSel->GetRangeAt(i, getter_AddRefs(range));
|
||||
mArray[i].StoreRange(range);
|
||||
mArray[i]->StoreRange(range);
|
||||
}
|
||||
|
||||
return res;
|
||||
@ -91,7 +92,7 @@ nsSelectionState::RestoreSelection(nsISelection *aSel)
|
||||
for (i=0; i<arrayCount; i++)
|
||||
{
|
||||
nsRefPtr<nsRange> range;
|
||||
mArray[i].GetRange(getter_AddRefs(range));
|
||||
mArray[i]->GetRange(getter_AddRefs(range));
|
||||
NS_ENSURE_TRUE(range, NS_ERROR_UNEXPECTED);
|
||||
|
||||
res = aSel->AddRange(range);
|
||||
@ -106,7 +107,7 @@ nsSelectionState::IsCollapsed()
|
||||
{
|
||||
if (1 != mArray.Length()) return false;
|
||||
nsRefPtr<nsRange> range;
|
||||
mArray[0].GetRange(getter_AddRefs(range));
|
||||
mArray[0]->GetRange(getter_AddRefs(range));
|
||||
NS_ENSURE_TRUE(range, false);
|
||||
bool bIsCollapsed = false;
|
||||
range->GetCollapsed(&bIsCollapsed);
|
||||
@ -124,8 +125,8 @@ nsSelectionState::IsEqual(nsSelectionState *aSelState)
|
||||
for (i=0; i<myCount; i++)
|
||||
{
|
||||
nsRefPtr<nsRange> myRange, itsRange;
|
||||
mArray[i].GetRange(getter_AddRefs(myRange));
|
||||
aSelState->mArray[i].GetRange(getter_AddRefs(itsRange));
|
||||
mArray[i]->GetRange(getter_AddRefs(myRange));
|
||||
aSelState->mArray[i]->GetRange(getter_AddRefs(itsRange));
|
||||
NS_ENSURE_TRUE(myRange && itsRange, false);
|
||||
|
||||
PRInt16 compResult;
|
||||
@ -190,7 +191,7 @@ nsRangeUpdater::RegisterSelectionState(nsSelectionState &aSelState)
|
||||
|
||||
for (i=0; i<theCount; i++)
|
||||
{
|
||||
RegisterRangeItem(&aSelState.mArray[i]);
|
||||
RegisterRangeItem(aSelState.mArray[i]);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@ -204,7 +205,7 @@ nsRangeUpdater::DropSelectionState(nsSelectionState &aSelState)
|
||||
|
||||
for (i=0; i<theCount; i++)
|
||||
{
|
||||
DropRangeItem(&aSelState.mArray[i]);
|
||||
DropRangeItem(aSelState.mArray[i]);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -30,6 +30,8 @@ struct nsRangeStore
|
||||
~nsRangeStore();
|
||||
nsresult StoreRange(nsIDOMRange *aRange);
|
||||
nsresult GetRange(nsRange** outRange);
|
||||
|
||||
NS_INLINE_DECL_REFCOUNTING(nsRangeStore)
|
||||
|
||||
nsCOMPtr<nsIDOMNode> startNode;
|
||||
PRInt32 startOffset;
|
||||
@ -55,7 +57,7 @@ class nsSelectionState
|
||||
void MakeEmpty();
|
||||
bool IsEmpty();
|
||||
protected:
|
||||
nsTArray<nsRangeStore> mArray;
|
||||
nsTArray<nsRefPtr<nsRangeStore> > mArray;
|
||||
|
||||
friend class nsRangeUpdater;
|
||||
};
|
||||
@ -99,7 +101,7 @@ class nsRangeUpdater
|
||||
nsresult WillMoveNode();
|
||||
nsresult DidMoveNode(nsIDOMNode *aOldParent, PRInt32 aOldOffset, nsIDOMNode *aNewParent, PRInt32 aNewOffset);
|
||||
protected:
|
||||
nsTArray<nsRangeStore*> mArray;
|
||||
nsTArray<nsRefPtr<nsRangeStore> > mArray;
|
||||
bool mLock;
|
||||
};
|
||||
|
||||
@ -115,25 +117,26 @@ class NS_STACK_CLASS nsAutoTrackDOMPoint
|
||||
nsRangeUpdater &mRU;
|
||||
nsCOMPtr<nsIDOMNode> *mNode;
|
||||
PRInt32 *mOffset;
|
||||
nsRangeStore mRangeItem;
|
||||
nsRefPtr<nsRangeStore> mRangeItem;
|
||||
public:
|
||||
nsAutoTrackDOMPoint(nsRangeUpdater &aRangeUpdater, nsCOMPtr<nsIDOMNode> *aNode, PRInt32 *aOffset) :
|
||||
mRU(aRangeUpdater)
|
||||
,mNode(aNode)
|
||||
,mOffset(aOffset)
|
||||
{
|
||||
mRangeItem.startNode = *mNode;
|
||||
mRangeItem.endNode = *mNode;
|
||||
mRangeItem.startOffset = *mOffset;
|
||||
mRangeItem.endOffset = *mOffset;
|
||||
mRU.RegisterRangeItem(&mRangeItem);
|
||||
mRangeItem = new nsRangeStore();
|
||||
mRangeItem->startNode = *mNode;
|
||||
mRangeItem->endNode = *mNode;
|
||||
mRangeItem->startOffset = *mOffset;
|
||||
mRangeItem->endOffset = *mOffset;
|
||||
mRU.RegisterRangeItem(mRangeItem);
|
||||
}
|
||||
|
||||
~nsAutoTrackDOMPoint()
|
||||
{
|
||||
mRU.DropRangeItem(&mRangeItem);
|
||||
*mNode = mRangeItem.startNode;
|
||||
*mOffset = mRangeItem.startOffset;
|
||||
mRU.DropRangeItem(mRangeItem);
|
||||
*mNode = mRangeItem->startNode;
|
||||
*mOffset = mRangeItem->startOffset;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -184,6 +184,7 @@ mDocChangeRange(nsnull)
|
||||
mCachedStyles[16] = StyleCache(nsEditProperty::cssBackgroundColor, EmptyString(), EmptyString());
|
||||
mCachedStyles[17] = StyleCache(nsEditProperty::sub, EmptyString(), EmptyString());
|
||||
mCachedStyles[18] = StyleCache(nsEditProperty::sup, EmptyString(), EmptyString());
|
||||
mRangeItem = new nsRangeStore();
|
||||
}
|
||||
|
||||
nsHTMLEditRules::~nsHTMLEditRules()
|
||||
@ -287,17 +288,17 @@ nsHTMLEditRules::BeforeEdit(nsEditor::OperationID action,
|
||||
PRInt32 selOffset;
|
||||
res = mHTMLEditor->GetStartNodeAndOffset(selection, getter_AddRefs(selStartNode), &selOffset);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
mRangeItem.startNode = selStartNode;
|
||||
mRangeItem.startOffset = selOffset;
|
||||
mRangeItem->startNode = selStartNode;
|
||||
mRangeItem->startOffset = selOffset;
|
||||
|
||||
// get the selection end location
|
||||
res = mHTMLEditor->GetEndNodeAndOffset(selection, getter_AddRefs(selEndNode), &selOffset);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
mRangeItem.endNode = selEndNode;
|
||||
mRangeItem.endOffset = selOffset;
|
||||
mRangeItem->endNode = selEndNode;
|
||||
mRangeItem->endOffset = selOffset;
|
||||
|
||||
// register this range with range updater to track this as we perturb the doc
|
||||
(mHTMLEditor->mRangeUpdater).RegisterRangeItem(&mRangeItem);
|
||||
(mHTMLEditor->mRangeUpdater).RegisterRangeItem(mRangeItem);
|
||||
|
||||
// clear deletion state bool
|
||||
mDidDeleteSelection = false;
|
||||
@ -361,7 +362,7 @@ nsHTMLEditRules::AfterEdit(nsEditor::OperationID action,
|
||||
res = AfterEditInner(action, aDirection);
|
||||
|
||||
// free up selectionState range item
|
||||
(mHTMLEditor->mRangeUpdater).DropRangeItem(&mRangeItem);
|
||||
(mHTMLEditor->mRangeUpdater).DropRangeItem(mRangeItem);
|
||||
|
||||
// Reset the contenteditable count to its previous value
|
||||
if (mRestoreContentEditableCount) {
|
||||
@ -453,11 +454,13 @@ nsHTMLEditRules::AfterEditInner(nsEditor::OperationID action,
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
|
||||
// also do this for original selection endpoints.
|
||||
nsWSRunObject(mHTMLEditor, mRangeItem.startNode, mRangeItem.startOffset).AdjustWhitespace();
|
||||
nsWSRunObject(mHTMLEditor, mRangeItem->startNode,
|
||||
mRangeItem->startOffset).AdjustWhitespace();
|
||||
// we only need to handle old selection endpoint if it was different from start
|
||||
if ((mRangeItem.startNode != mRangeItem.endNode) || (mRangeItem.startOffset != mRangeItem.endOffset))
|
||||
{
|
||||
nsWSRunObject(mHTMLEditor, mRangeItem.endNode, mRangeItem.endOffset).AdjustWhitespace();
|
||||
if (mRangeItem->startNode != mRangeItem->endNode ||
|
||||
mRangeItem->startOffset != mRangeItem->endOffset) {
|
||||
nsWSRunObject(mHTMLEditor, mRangeItem->endNode,
|
||||
mRangeItem->endOffset).AdjustWhitespace();
|
||||
}
|
||||
}
|
||||
|
||||
@ -494,7 +497,8 @@ nsHTMLEditRules::AfterEditInner(nsEditor::OperationID action,
|
||||
}
|
||||
|
||||
res = mHTMLEditor->HandleInlineSpellCheck(action, selection,
|
||||
mRangeItem.startNode, mRangeItem.startOffset,
|
||||
mRangeItem->startNode,
|
||||
mRangeItem->startOffset,
|
||||
rangeStartParent, rangeStartOffset,
|
||||
rangeEndParent, rangeEndOffset);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
@ -5572,7 +5576,7 @@ nsHTMLEditRules::GetNodesForOperation(nsCOMArray<nsIDOMRange>& inArrayOfRanges,
|
||||
|
||||
if (!aDontTouchContent)
|
||||
{
|
||||
nsAutoTArray<nsRangeStore, 16> rangeItemArray;
|
||||
nsTArray<nsRefPtr<nsRangeStore> > rangeItemArray;
|
||||
if (!rangeItemArray.AppendElements(rangeCount)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
@ -5584,21 +5588,21 @@ nsHTMLEditRules::GetNodesForOperation(nsCOMArray<nsIDOMRange>& inArrayOfRanges,
|
||||
for (i = 0; i < rangeCount; i++)
|
||||
{
|
||||
opRange = inArrayOfRanges[0];
|
||||
nsRangeStore *item = rangeItemArray.Elements() + i;
|
||||
item->StoreRange(opRange);
|
||||
mHTMLEditor->mRangeUpdater.RegisterRangeItem(item);
|
||||
rangeItemArray[i] = new nsRangeStore();
|
||||
rangeItemArray[i]->StoreRange(opRange);
|
||||
mHTMLEditor->mRangeUpdater.RegisterRangeItem(rangeItemArray[i]);
|
||||
inArrayOfRanges.RemoveObjectAt(0);
|
||||
}
|
||||
// now bust up inlines. Safe to start at rangeCount-1, since we
|
||||
// asserted we have enough items above.
|
||||
for (i = rangeCount-1; i >= 0 && NS_SUCCEEDED(res); i--)
|
||||
{
|
||||
res = BustUpInlinesAtRangeEndpoints(rangeItemArray[i]);
|
||||
res = BustUpInlinesAtRangeEndpoints(*rangeItemArray[i]);
|
||||
}
|
||||
// then unregister the ranges
|
||||
for (i = 0; i < rangeCount; i++)
|
||||
{
|
||||
nsRangeStore *item = rangeItemArray.Elements() + i;
|
||||
nsRangeStore* item = rangeItemArray[i];
|
||||
mHTMLEditor->mRangeUpdater.DropRangeItem(item);
|
||||
nsRefPtr<nsRange> range;
|
||||
nsresult res2 = item->GetRange(getter_AddRefs(range));
|
||||
|
@ -293,7 +293,7 @@ protected:
|
||||
nsRefPtr<nsRange> mUtilRange;
|
||||
PRUint32 mJoinOffset; // need to remember an int across willJoin/didJoin...
|
||||
nsCOMPtr<nsIDOMNode> mNewBlock;
|
||||
nsRangeStore mRangeItem;
|
||||
nsRefPtr<nsRangeStore> mRangeItem;
|
||||
StyleCache mCachedStyles[SIZE_STYLE_TABLE];
|
||||
};
|
||||
|
||||
|
@ -648,7 +648,8 @@ nsTextEditRules::WillInsertText(nsEditor::OperationID aAction,
|
||||
mTimer = do_CreateInstance("@mozilla.org/timer;1", &res);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
}
|
||||
mTimer->InitWithCallback(this, 600, nsITimer::TYPE_ONE_SHOT);
|
||||
mTimer->InitWithCallback(this, LookAndFeel::GetPasswordMaskDelay(),
|
||||
nsITimer::TYPE_ONE_SHOT);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "nsAppDirectoryServiceDefs.h"
|
||||
#include "prprf.h"
|
||||
#include "mozilla/storage.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "nsIPrincipal.h"
|
||||
|
||||
@ -115,7 +116,7 @@ nsHostEntry::nsHostEntry(const nsHostEntry& toCopy)
|
||||
* Note: Once the callback has been called this DeleteFromMozHostListener cannot
|
||||
* be reused.
|
||||
*/
|
||||
class CloseDatabaseListener : public mozIStorageCompletionCallback
|
||||
class CloseDatabaseListener MOZ_FINAL : public mozIStorageCompletionCallback
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
@ -164,7 +165,7 @@ CloseDatabaseListener::Complete()
|
||||
* Note: Once the callback has been called this DeleteFromMozHostListener cannot
|
||||
* be reused.
|
||||
*/
|
||||
class DeleteFromMozHostListener : public mozIStorageStatementCallback
|
||||
class DeleteFromMozHostListener MOZ_FINAL : public mozIStorageStatementCallback
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
@ -140,6 +140,14 @@ EXPORTS_mozilla/layers += ShadowLayerUtilsD3D10.h
|
||||
DEFINES += -DMOZ_ENABLE_D3D10_LAYER
|
||||
endif
|
||||
|
||||
# NB: Gralloc is available on other platforms that use the android GL
|
||||
# libraries, but only Gonk is able to use it reliably because Gecko
|
||||
# has full system permissions there.
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),gonk)
|
||||
EXPORTS_mozilla/layers += ShadowLayerUtilsGralloc.h
|
||||
CPPSRCS += ShadowLayerUtilsGralloc.cpp
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
include $(topsrcdir)/ipc/chromium/chromium-config.mk
|
||||
|
@ -171,6 +171,16 @@ protected:
|
||||
return tmp.forget();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the buffer only. This is intended to be used with the
|
||||
* shadow-layer Open/CloseDescriptor interface, to ensure we don't
|
||||
* accidentally touch a buffer when it's not mapped.
|
||||
*/
|
||||
void SetBuffer(gfxASurface* aBuffer)
|
||||
{
|
||||
mBuffer = aBuffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a context at the specified resolution for updating |aBounds|,
|
||||
* which must be contained within a single quadrant.
|
||||
|
@ -10,8 +10,8 @@
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
namespace layers {
|
||||
|
||||
|
||||
static bool
|
||||
IsClippingCheap(gfxContext* aTarget, const nsIntRegion& aRegion)
|
||||
@ -47,10 +47,10 @@ BasicThebesLayerBuffer::DrawTo(ThebesLayer* aLayer,
|
||||
|
||||
// Pull out the mask surface and transform here, because the mask
|
||||
// is internal to basic layers
|
||||
gfxMatrix maskTransform;
|
||||
if (nsRefPtr<gfxASurface> maskSurface =
|
||||
GetMaskSurfaceAndTransform(aMaskLayer, &maskTransform)) {
|
||||
DrawBufferWithRotation(aTarget, aOpacity, maskSurface, &maskTransform);
|
||||
AutoMaskData mask;
|
||||
if (GetMaskData(aMaskLayer, &mask)) {
|
||||
DrawBufferWithRotation(aTarget, aOpacity,
|
||||
mask.GetSurface(), &mask.GetTransform());
|
||||
} else {
|
||||
DrawBufferWithRotation(aTarget, aOpacity);
|
||||
}
|
||||
|
@ -58,6 +58,27 @@ public:
|
||||
gfxASurface* aSource, const nsIntRect& aRect, const nsIntPoint& aRotation,
|
||||
const nsIntRegion& aUpdateRegion);
|
||||
|
||||
/**
|
||||
* When BasicThebesLayerBuffer is used with layers that hold
|
||||
* SurfaceDescriptor, this buffer only has a valid gfxASurface in
|
||||
* the scope of an AutoOpenSurface for that SurfaceDescriptor. That
|
||||
* is, it's sort of a "virtual buffer" that's only mapped an
|
||||
* unmapped within the scope of AutoOpenSurface. None of the
|
||||
* underlying buffer attributes (rect, rotation) are affected by
|
||||
* mapping/unmapping.
|
||||
*
|
||||
* These helpers just exist to provide more descriptive names of the
|
||||
* map/unmap process.
|
||||
*/
|
||||
void MapBuffer(gfxASurface* aBuffer)
|
||||
{
|
||||
SetBuffer(aBuffer);
|
||||
}
|
||||
void UnmapBuffer()
|
||||
{
|
||||
SetBuffer(nsnull);
|
||||
}
|
||||
|
||||
private:
|
||||
BasicThebesLayerBuffer(gfxASurface* aBuffer,
|
||||
const nsIntRect& aRect, const nsIntPoint& aRotation)
|
||||
@ -87,18 +108,25 @@ public:
|
||||
MOZ_COUNT_DTOR(ShadowThebesLayerBuffer);
|
||||
}
|
||||
|
||||
void Swap(gfxASurface* aNewBuffer,
|
||||
const nsIntRect& aNewRect, const nsIntPoint& aNewRotation,
|
||||
gfxASurface** aOldBuffer,
|
||||
/**
|
||||
* Swap in the old "virtual buffer" (see above) attributes in aNew*
|
||||
* and return the old ones in aOld*.
|
||||
*
|
||||
* Swap() must only be called when the buffer is in its "unmapped"
|
||||
* state, that is the underlying gfxASurface is not available. It
|
||||
* is expected that the owner of this buffer holds an unmapped
|
||||
* SurfaceDescriptor as the backing storage for this buffer. That's
|
||||
* why no gfxASurface or SurfaceDescriptor parameters appear here.
|
||||
*/
|
||||
void Swap(const nsIntRect& aNewRect, const nsIntPoint& aNewRotation,
|
||||
nsIntRect* aOldRect, nsIntPoint* aOldRotation)
|
||||
{
|
||||
*aOldRect = BufferRect();
|
||||
*aOldRotation = BufferRotation();
|
||||
|
||||
nsRefPtr<gfxASurface> oldBuffer;
|
||||
oldBuffer = SetBuffer(aNewBuffer,
|
||||
aNewRect, aNewRotation);
|
||||
oldBuffer.forget(aOldBuffer);
|
||||
oldBuffer = SetBuffer(nsnull, aNewRect, aNewRotation);
|
||||
MOZ_ASSERT(!oldBuffer);
|
||||
}
|
||||
|
||||
protected:
|
||||
@ -113,4 +141,4 @@ protected:
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -339,9 +339,8 @@ BasicShadowableCanvasLayer::Initialize(const Data& aData)
|
||||
// canvas resizes
|
||||
|
||||
if (IsSurfaceDescriptorValid(mBackBuffer)) {
|
||||
nsRefPtr<gfxASurface> backSurface =
|
||||
BasicManager()->OpenDescriptor(mBackBuffer);
|
||||
if (gfxIntSize(mBounds.width, mBounds.height) != backSurface->GetSize()) {
|
||||
AutoOpenSurface backSurface(OPEN_READ_ONLY, mBackBuffer);
|
||||
if (gfxIntSize(mBounds.width, mBounds.height) != backSurface.Size()) {
|
||||
DestroyBackBuffer();
|
||||
}
|
||||
}
|
||||
@ -368,15 +367,13 @@ BasicShadowableCanvasLayer::Paint(gfxContext* aContext, Layer* aMaskLayer)
|
||||
NS_RUNTIMEABORT("creating CanvasLayer back buffer failed!");
|
||||
}
|
||||
|
||||
nsRefPtr<gfxASurface> backSurface =
|
||||
BasicManager()->OpenDescriptor(mBackBuffer);
|
||||
|
||||
AutoOpenSurface autoBackSurface(OPEN_READ_WRITE, mBackBuffer);
|
||||
|
||||
if (aMaskLayer) {
|
||||
static_cast<BasicImplData*>(aMaskLayer->ImplData())
|
||||
->Paint(aContext, nsnull);
|
||||
}
|
||||
UpdateSurface(backSurface, nsnull);
|
||||
UpdateSurface(autoBackSurface.Get(), nsnull);
|
||||
FireDidTransactionCallback();
|
||||
|
||||
BasicManager()->PaintedCanvas(BasicManager()->Hold(this),
|
||||
@ -437,15 +434,14 @@ void
|
||||
BasicShadowCanvasLayer::Swap(const CanvasSurface& aNewFront, bool needYFlip,
|
||||
CanvasSurface* aNewBack)
|
||||
{
|
||||
nsRefPtr<gfxASurface> surface =
|
||||
BasicManager()->OpenDescriptor(aNewFront);
|
||||
AutoOpenSurface autoSurface(OPEN_READ_ONLY, aNewFront);
|
||||
// Destroy mFrontBuffer if size different
|
||||
gfxIntSize sz = surface->GetSize();
|
||||
gfxIntSize sz = autoSurface.Size();
|
||||
bool surfaceConfigChanged = sz != gfxIntSize(mBounds.width, mBounds.height);
|
||||
if (IsSurfaceDescriptorValid(mFrontSurface)) {
|
||||
nsRefPtr<gfxASurface> front = BasicManager()->OpenDescriptor(mFrontSurface);
|
||||
AutoOpenSurface autoFront(OPEN_READ_ONLY, mFrontSurface);
|
||||
surfaceConfigChanged = surfaceConfigChanged ||
|
||||
surface->GetContentType() != front->GetContentType();
|
||||
autoSurface.ContentType() != autoFront.ContentType();
|
||||
}
|
||||
if (surfaceConfigChanged) {
|
||||
DestroyFrontBuffer();
|
||||
@ -459,7 +455,7 @@ BasicShadowCanvasLayer::Swap(const CanvasSurface& aNewFront, bool needYFlip,
|
||||
} else {
|
||||
*aNewBack = null_t();
|
||||
}
|
||||
mFrontSurface = aNewFront.get_SurfaceDescriptor();
|
||||
mFrontSurface = aNewFront;
|
||||
}
|
||||
|
||||
void
|
||||
@ -472,9 +468,8 @@ BasicShadowCanvasLayer::Paint(gfxContext* aContext, Layer* aMaskLayer)
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<gfxASurface> surface =
|
||||
BasicManager()->OpenDescriptor(mFrontSurface);
|
||||
nsRefPtr<gfxPattern> pat = new gfxPattern(surface);
|
||||
AutoOpenSurface autoSurface(OPEN_READ_ONLY, mFrontSurface);
|
||||
nsRefPtr<gfxPattern> pat = new gfxPattern(autoSurface.Get());
|
||||
|
||||
pat->SetFilter(mFilter);
|
||||
pat->SetExtend(gfxPattern::EXTEND_PAD);
|
||||
|
@ -9,8 +9,8 @@
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
namespace layers {
|
||||
|
||||
class BasicColorLayer : public ColorLayer, public BasicImplData {
|
||||
public:
|
||||
BasicColorLayer(BasicLayerManager* aLayerManager) :
|
||||
|
@ -9,8 +9,8 @@
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
namespace layers {
|
||||
|
||||
|
||||
|
||||
BasicContainerLayer::~BasicContainerLayer()
|
||||
|
@ -11,7 +11,7 @@
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
namespace layers {
|
||||
|
||||
class BasicImageLayer : public ImageLayer, public BasicImplData {
|
||||
public:
|
||||
@ -41,7 +41,8 @@ public:
|
||||
gfxContext* aContext,
|
||||
Layer* aMaskLayer);
|
||||
|
||||
virtual already_AddRefed<gfxASurface> GetAsSurface();
|
||||
virtual bool GetAsSurface(gfxASurface** aSurface,
|
||||
SurfaceDescriptor* aDescriptor);
|
||||
|
||||
protected:
|
||||
BasicLayerManager* BasicManager()
|
||||
@ -86,9 +87,6 @@ BasicImageLayer::GetAndPaintCurrentImage(gfxContext* aContext,
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
NS_ASSERTION(surface->GetContentType() != gfxASurface::CONTENT_ALPHA,
|
||||
"Image layer has alpha image");
|
||||
|
||||
nsRefPtr<gfxPattern> pat = new gfxPattern(surface);
|
||||
if (!pat) {
|
||||
return nsnull;
|
||||
@ -154,15 +152,18 @@ BasicImageLayer::PaintContext(gfxPattern* aPattern,
|
||||
aPattern->SetExtend(extend);
|
||||
}
|
||||
|
||||
already_AddRefed<gfxASurface>
|
||||
BasicImageLayer::GetAsSurface()
|
||||
bool
|
||||
BasicImageLayer::GetAsSurface(gfxASurface** aSurface,
|
||||
SurfaceDescriptor* aDescriptor)
|
||||
{
|
||||
if (!mContainer) {
|
||||
return nsnull;
|
||||
return false;
|
||||
}
|
||||
|
||||
gfxIntSize dontCare;
|
||||
return mContainer->GetCurrentAsSurface(&dontCare);
|
||||
nsRefPtr<gfxASurface> surface = mContainer->GetCurrentAsSurface(&dontCare);
|
||||
*aSurface = surface.forget().get();
|
||||
return true;
|
||||
}
|
||||
|
||||
class BasicShadowableImageLayer : public BasicImageLayer,
|
||||
@ -196,9 +197,9 @@ public:
|
||||
mBackBuffer = aBuffer;
|
||||
}
|
||||
|
||||
virtual void SetBackBufferYUVImage(gfxSharedImageSurface* aYBuffer,
|
||||
gfxSharedImageSurface* aUBuffer,
|
||||
gfxSharedImageSurface* aVBuffer)
|
||||
virtual void SetBackBufferYUVImage(const SurfaceDescriptor& aYBuffer,
|
||||
const SurfaceDescriptor& aUBuffer,
|
||||
const SurfaceDescriptor& aVBuffer)
|
||||
{
|
||||
mBackBufferY = aYBuffer;
|
||||
mBackBufferU = aUBuffer;
|
||||
@ -207,7 +208,9 @@ public:
|
||||
|
||||
virtual void Disconnect()
|
||||
{
|
||||
mBackBufferY = mBackBufferU = mBackBufferV = nsnull;
|
||||
mBackBufferY = SurfaceDescriptor();
|
||||
mBackBufferU = SurfaceDescriptor();
|
||||
mBackBufferV = SurfaceDescriptor();
|
||||
mBackBuffer = SurfaceDescriptor();
|
||||
BasicShadowableLayer::Disconnect();
|
||||
}
|
||||
@ -217,11 +220,11 @@ public:
|
||||
if (IsSurfaceDescriptorValid(mBackBuffer)) {
|
||||
BasicManager()->ShadowLayerForwarder::DestroySharedSurface(&mBackBuffer);
|
||||
}
|
||||
if (mBackBufferY) {
|
||||
BasicManager()->ShadowLayerForwarder::DestroySharedSurface(mBackBufferY);
|
||||
BasicManager()->ShadowLayerForwarder::DestroySharedSurface(mBackBufferU);
|
||||
BasicManager()->ShadowLayerForwarder::DestroySharedSurface(mBackBufferV);
|
||||
}
|
||||
if (IsSurfaceDescriptorValid(mBackBufferY)) {
|
||||
BasicManager()->ShadowLayerForwarder::DestroySharedSurface(&mBackBufferY);
|
||||
BasicManager()->ShadowLayerForwarder::DestroySharedSurface(&mBackBufferU);
|
||||
BasicManager()->ShadowLayerForwarder::DestroySharedSurface(&mBackBufferV);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
@ -234,9 +237,9 @@ private:
|
||||
// for RGB images only mBackSurface is used.
|
||||
SurfaceDescriptor mBackBuffer;
|
||||
bool mBufferIsOpaque;
|
||||
nsRefPtr<gfxSharedImageSurface> mBackBufferY;
|
||||
nsRefPtr<gfxSharedImageSurface> mBackBufferU;
|
||||
nsRefPtr<gfxSharedImageSurface> mBackBufferV;
|
||||
SurfaceDescriptor mBackBufferY;
|
||||
SurfaceDescriptor mBackBufferU;
|
||||
SurfaceDescriptor mBackBufferV;
|
||||
gfxIntSize mCbCrSize;
|
||||
};
|
||||
|
||||
@ -271,38 +274,52 @@ BasicShadowableImageLayer::Paint(gfxContext* aContext, Layer* aMaskLayer)
|
||||
const PlanarYCbCrImage::Data *data = YCbCrImage->GetData();
|
||||
NS_ASSERTION(data, "Must be able to retrieve yuv data from image!");
|
||||
|
||||
if (mSize != data->mYSize || mCbCrSize != data->mCbCrSize || !mBackBufferY) {
|
||||
if (mSize != data->mYSize || mCbCrSize != data->mCbCrSize || !IsSurfaceDescriptorValid(mBackBufferY)) {
|
||||
DestroyBackBuffer();
|
||||
mSize = data->mYSize;
|
||||
mCbCrSize = data->mCbCrSize;
|
||||
|
||||
if (!BasicManager()->AllocBuffer(mSize, gfxASurface::CONTENT_ALPHA,
|
||||
getter_AddRefs(mBackBufferY)) ||
|
||||
!BasicManager()->AllocBuffer(mCbCrSize, gfxASurface::CONTENT_ALPHA,
|
||||
getter_AddRefs(mBackBufferU)) ||
|
||||
!BasicManager()->AllocBuffer(mCbCrSize, gfxASurface::CONTENT_ALPHA,
|
||||
getter_AddRefs(mBackBufferV))) {
|
||||
// We either allocate all three planes or none.
|
||||
if (!BasicManager()->AllocBufferWithCaps(mSize,
|
||||
gfxASurface::CONTENT_ALPHA,
|
||||
MAP_AS_IMAGE_SURFACE,
|
||||
&mBackBufferY) ||
|
||||
!BasicManager()->AllocBufferWithCaps(mCbCrSize,
|
||||
gfxASurface::CONTENT_ALPHA,
|
||||
MAP_AS_IMAGE_SURFACE,
|
||||
&mBackBufferU) ||
|
||||
!BasicManager()->AllocBufferWithCaps(mCbCrSize,
|
||||
gfxASurface::CONTENT_ALPHA,
|
||||
MAP_AS_IMAGE_SURFACE,
|
||||
&mBackBufferV)) {
|
||||
NS_RUNTIMEABORT("creating ImageLayer 'front buffer' failed!");
|
||||
}
|
||||
}
|
||||
|
||||
AutoOpenSurface dyas(OPEN_READ_WRITE, mBackBufferY);
|
||||
gfxImageSurface* dy = dyas.GetAsImage();
|
||||
|
||||
for (int i = 0; i < data->mYSize.height; i++) {
|
||||
memcpy(mBackBufferY->Data() + i * mBackBufferY->Stride(),
|
||||
memcpy(dy->Data() + i * dy->Stride(),
|
||||
data->mYChannel + i * data->mYStride,
|
||||
data->mYSize.width);
|
||||
}
|
||||
|
||||
AutoOpenSurface duas(OPEN_READ_WRITE, mBackBufferU);
|
||||
gfxImageSurface* du = duas.GetAsImage();
|
||||
AutoOpenSurface dvas(OPEN_READ_WRITE, mBackBufferV);
|
||||
gfxImageSurface* dv = dvas.GetAsImage();
|
||||
|
||||
for (int i = 0; i < data->mCbCrSize.height; i++) {
|
||||
memcpy(mBackBufferU->Data() + i * mBackBufferU->Stride(),
|
||||
memcpy(du->Data() + i * du->Stride(),
|
||||
data->mCbChannel + i * data->mCbCrStride,
|
||||
data->mCbCrSize.width);
|
||||
memcpy(mBackBufferV->Data() + i * mBackBufferV->Stride(),
|
||||
memcpy(dv->Data() + i * dv->Stride(),
|
||||
data->mCrChannel + i * data->mCbCrStride,
|
||||
data->mCbCrSize.width);
|
||||
}
|
||||
|
||||
YUVImage yuv(mBackBufferY->GetShmem(),
|
||||
mBackBufferU->GetShmem(),
|
||||
mBackBufferV->GetShmem(),
|
||||
YUVImage yuv(mBackBufferY, mBackBufferU, mBackBufferV,
|
||||
data->GetPictureRect());
|
||||
|
||||
BasicManager()->PaintedImage(BasicManager()->Hold(this),
|
||||
@ -336,9 +353,8 @@ BasicShadowableImageLayer::Paint(gfxContext* aContext, Layer* aMaskLayer)
|
||||
NS_RUNTIMEABORT("creating ImageLayer 'front buffer' failed!");
|
||||
}
|
||||
|
||||
nsRefPtr<gfxASurface> backSurface =
|
||||
BasicManager()->OpenDescriptor(mBackBuffer);
|
||||
nsRefPtr<gfxContext> tmpCtx = new gfxContext(backSurface);
|
||||
AutoOpenSurface backSurface(OPEN_READ_WRITE, mBackBuffer);
|
||||
nsRefPtr<gfxContext> tmpCtx = new gfxContext(backSurface.Get());
|
||||
tmpCtx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
PaintContext(pat,
|
||||
nsIntRegion(nsIntRect(0, 0, mSize.width, mSize.height)),
|
||||
@ -377,7 +393,8 @@ public:
|
||||
}
|
||||
|
||||
virtual void Paint(gfxContext* aContext, Layer* aMaskLayer);
|
||||
already_AddRefed<gfxASurface> GetAsSurface();
|
||||
virtual bool GetAsSurface(gfxASurface** aSurface,
|
||||
SurfaceDescriptor* aDescriptor);
|
||||
|
||||
protected:
|
||||
BasicShadowLayerManager* BasicManager()
|
||||
@ -393,18 +410,17 @@ void
|
||||
BasicShadowImageLayer::Swap(const SharedImage& aNewFront,
|
||||
SharedImage* aNewBack)
|
||||
{
|
||||
nsRefPtr<gfxASurface> surface =
|
||||
BasicManager()->OpenDescriptor(aNewFront);
|
||||
AutoOpenSurface autoSurface(OPEN_READ_ONLY, aNewFront);
|
||||
// Destroy mFrontBuffer if size different or image type is different
|
||||
bool surfaceConfigChanged = surface->GetSize() != mSize;
|
||||
bool surfaceConfigChanged = autoSurface.Size() != mSize;
|
||||
if (IsSurfaceDescriptorValid(mFrontBuffer)) {
|
||||
nsRefPtr<gfxASurface> front = BasicManager()->OpenDescriptor(mFrontBuffer);
|
||||
AutoOpenSurface autoFront(OPEN_READ_ONLY, mFrontBuffer);
|
||||
surfaceConfigChanged = surfaceConfigChanged ||
|
||||
surface->GetContentType() != front->GetContentType();
|
||||
autoSurface.ContentType() != autoFront.ContentType();
|
||||
}
|
||||
if (surfaceConfigChanged) {
|
||||
DestroyFrontBuffer();
|
||||
mSize = surface->GetSize();
|
||||
mSize = autoSurface.Size();
|
||||
}
|
||||
|
||||
// If mFrontBuffer
|
||||
@ -413,7 +429,7 @@ BasicShadowImageLayer::Swap(const SharedImage& aNewFront,
|
||||
} else {
|
||||
*aNewBack = null_t();
|
||||
}
|
||||
mFrontBuffer = aNewFront.get_SurfaceDescriptor();
|
||||
mFrontBuffer = aNewFront;
|
||||
}
|
||||
|
||||
void
|
||||
@ -423,9 +439,8 @@ BasicShadowImageLayer::Paint(gfxContext* aContext, Layer* aMaskLayer)
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<gfxASurface> surface =
|
||||
BasicManager()->OpenDescriptor(mFrontBuffer);
|
||||
nsRefPtr<gfxPattern> pat = new gfxPattern(surface);
|
||||
AutoOpenSurface autoSurface(OPEN_READ_ONLY, mFrontBuffer);
|
||||
nsRefPtr<gfxPattern> pat = new gfxPattern(autoSurface.Get());
|
||||
pat->SetFilter(mFilter);
|
||||
|
||||
// The visible region can extend outside the image, so just draw
|
||||
@ -437,14 +452,16 @@ BasicShadowImageLayer::Paint(gfxContext* aContext, Layer* aMaskLayer)
|
||||
aMaskLayer);
|
||||
}
|
||||
|
||||
already_AddRefed<gfxASurface>
|
||||
BasicShadowImageLayer::GetAsSurface()
|
||||
bool
|
||||
BasicShadowImageLayer::GetAsSurface(gfxASurface** aSurface,
|
||||
SurfaceDescriptor* aDescriptor)
|
||||
{
|
||||
if (!IsSurfaceDescriptorValid(mFrontBuffer)) {
|
||||
return nsnull;
|
||||
return false;
|
||||
}
|
||||
|
||||
return BasicManager()->OpenDescriptor(mFrontBuffer);
|
||||
*aDescriptor = mFrontBuffer;
|
||||
return true;
|
||||
}
|
||||
|
||||
already_AddRefed<ImageLayer>
|
||||
|
@ -101,11 +101,14 @@ public:
|
||||
|
||||
/**
|
||||
* Return a surface for this layer. Will use an existing surface, if
|
||||
* possible, or may create a temporary surface.
|
||||
* Implement this method for any layers that might be used as a mask.
|
||||
* Should only return null if a surface cannor be created.
|
||||
* possible, or may create a temporary surface. Implement this
|
||||
* method for any layers that might be used as a mask. Should only
|
||||
* return false if a surface cannot be created. If true is
|
||||
* returned, only one of |aSurface| or |aDescriptor| is valid.
|
||||
*/
|
||||
virtual already_AddRefed<gfxASurface> GetAsSurface() { return nsnull; }
|
||||
virtual bool GetAsSurface(gfxASurface** aSurface,
|
||||
SurfaceDescriptor* aDescriptor)
|
||||
{ return false; }
|
||||
|
||||
bool GetClipToVisibleRegion() { return mClipToVisibleRegion; }
|
||||
void SetClipToVisibleRegion(bool aClip) { mClipToVisibleRegion = aClip; }
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "gfxSharedImageSurface.h"
|
||||
#include "gfxImageSurface.h"
|
||||
#include "gfxUtils.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "RenderTrace.h"
|
||||
#include "sampler.h"
|
||||
|
||||
@ -24,7 +25,7 @@
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
namespace layers {
|
||||
|
||||
/**
|
||||
* Clips to the smallest device-pixel-aligned rectangle containing aRect
|
||||
@ -839,7 +840,6 @@ BasicLayerManager::PaintLayer(gfxContext* aTarget,
|
||||
gfxUtils::ClipToRegion(aTarget, aLayer->GetEffectiveVisibleRegion());
|
||||
}
|
||||
AutoSetOperator setOperator(aTarget, container->GetOperator());
|
||||
gfxMatrix temp = aTarget->CurrentMatrix();
|
||||
PaintWithMask(aTarget, aLayer->GetEffectiveOpacity(),
|
||||
HasShadowManager() ? nsnull : aLayer->GetMaskLayer());
|
||||
}
|
||||
@ -951,7 +951,8 @@ BasicShadowLayerManager::BeginTransactionWithTarget(gfxContext* aTarget)
|
||||
|
||||
// If we have a non-default target, we need to let our shadow manager draw
|
||||
// to it. This will happen at the end of the transaction.
|
||||
if (aTarget && (aTarget != mDefaultTarget)) {
|
||||
if (aTarget && (aTarget != mDefaultTarget) &&
|
||||
XRE_GetProcessType() == GeckoProcessType_Default) {
|
||||
mShadowTarget = aTarget;
|
||||
|
||||
// Create a temporary target for ourselves, so that mShadowTarget is only
|
||||
@ -1048,13 +1049,12 @@ BasicShadowLayerManager::ForwardTransaction()
|
||||
layer->SetBackBuffer(newBack.get_SurfaceDescriptor());
|
||||
} else if (newBack.type() == SharedImage::TYUVImage) {
|
||||
const YUVImage& yuv = newBack.get_YUVImage();
|
||||
nsRefPtr<gfxSharedImageSurface> YSurf = gfxSharedImageSurface::Open(yuv.Ydata());
|
||||
nsRefPtr<gfxSharedImageSurface> USurf = gfxSharedImageSurface::Open(yuv.Udata());
|
||||
nsRefPtr<gfxSharedImageSurface> VSurf = gfxSharedImageSurface::Open(yuv.Vdata());
|
||||
layer->SetBackBufferYUVImage(YSurf, USurf, VSurf);
|
||||
layer->SetBackBufferYUVImage(yuv.Ydata(), yuv.Udata(), yuv.Vdata());
|
||||
} else {
|
||||
layer->SetBackBuffer(SurfaceDescriptor());
|
||||
layer->SetBackBufferYUVImage(nsnull, nsnull, nsnull);
|
||||
layer->SetBackBufferYUVImage(SurfaceDescriptor(),
|
||||
SurfaceDescriptor(),
|
||||
SurfaceDescriptor());
|
||||
}
|
||||
|
||||
break;
|
||||
@ -1127,7 +1127,7 @@ BasicShadowLayerManager::CreateThebesLayer()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
BasicShadowableLayer::~BasicShadowableLayer()
|
||||
{
|
||||
if (HasShadow()) {
|
||||
|
@ -279,11 +279,11 @@ public:
|
||||
NS_RUNTIMEABORT("if this default impl is called, |aBuffer| leaks");
|
||||
}
|
||||
|
||||
virtual void SetBackBufferYUVImage(gfxSharedImageSurface* aYBuffer,
|
||||
gfxSharedImageSurface* aUBuffer,
|
||||
gfxSharedImageSurface* aVBuffer)
|
||||
virtual void SetBackBufferYUVImage(const SurfaceDescriptor& aYBuffer,
|
||||
const SurfaceDescriptor& aUBuffer,
|
||||
const SurfaceDescriptor& aVBuffer)
|
||||
{
|
||||
NS_RUNTIMEABORT("if this default impl is called, |aBuffer| leaks");
|
||||
NS_RUNTIMEABORT("if this default impl is called, the buffers leak");
|
||||
}
|
||||
|
||||
virtual void Disconnect()
|
||||
|
@ -4,65 +4,114 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "BasicLayersImpl.h"
|
||||
#include "mozilla/layers/PLayers.h"
|
||||
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
already_AddRefed<gfxASurface>
|
||||
GetMaskSurfaceAndTransform(Layer* aMaskLayer, gfxMatrix* aMaskTransform)
|
||||
|
||||
void
|
||||
AutoMaskData::Construct(const gfxMatrix& aTransform,
|
||||
gfxASurface* aSurface)
|
||||
{
|
||||
if (aMaskLayer) {
|
||||
nsRefPtr<gfxASurface> maskSurface =
|
||||
static_cast<BasicImplData*>(aMaskLayer->ImplData())->GetAsSurface();
|
||||
if (maskSurface) {
|
||||
bool maskIs2D =
|
||||
aMaskLayer->GetEffectiveTransform().CanDraw2D(aMaskTransform);
|
||||
NS_ASSERTION(maskIs2D, "How did we end up with a 3D transform here?!");
|
||||
return maskSurface.forget();
|
||||
}
|
||||
}
|
||||
return nsnull;
|
||||
MOZ_ASSERT(!IsConstructed());
|
||||
mTransform = aTransform;
|
||||
mSurface = aSurface;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AutoMaskData::Construct(const gfxMatrix& aTransform,
|
||||
const SurfaceDescriptor& aSurface)
|
||||
{
|
||||
MOZ_ASSERT(!IsConstructed());
|
||||
mTransform = aTransform;
|
||||
mSurfaceOpener.construct(OPEN_READ_ONLY, aSurface);
|
||||
}
|
||||
|
||||
gfxASurface*
|
||||
AutoMaskData::GetSurface()
|
||||
{
|
||||
MOZ_ASSERT(IsConstructed());
|
||||
if (mSurface) {
|
||||
return mSurface.get();
|
||||
}
|
||||
return mSurfaceOpener.ref().Get();
|
||||
}
|
||||
|
||||
const gfxMatrix&
|
||||
AutoMaskData::GetTransform()
|
||||
{
|
||||
MOZ_ASSERT(IsConstructed());
|
||||
return mTransform;
|
||||
}
|
||||
|
||||
bool
|
||||
AutoMaskData::IsConstructed()
|
||||
{
|
||||
return !!mSurface || !mSurfaceOpener.empty();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
GetMaskData(Layer* aMaskLayer, AutoMaskData* aMaskData)
|
||||
{
|
||||
if (aMaskLayer) {
|
||||
nsRefPtr<gfxASurface> surface;
|
||||
SurfaceDescriptor descriptor;
|
||||
if (static_cast<BasicImplData*>(aMaskLayer->ImplData())
|
||||
->GetAsSurface(getter_AddRefs(surface), &descriptor) &&
|
||||
(surface || IsSurfaceDescriptorValid(descriptor))) {
|
||||
gfxMatrix transform;
|
||||
DebugOnly<bool> maskIs2D =
|
||||
aMaskLayer->GetEffectiveTransform().CanDraw2D(&transform);
|
||||
NS_ASSERTION(maskIs2D, "How did we end up with a 3D transform here?!");
|
||||
if (surface) {
|
||||
aMaskData->Construct(transform, surface);
|
||||
} else {
|
||||
aMaskData->Construct(transform, descriptor);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
PaintWithMask(gfxContext* aContext, float aOpacity, Layer* aMaskLayer)
|
||||
{
|
||||
gfxMatrix maskTransform;
|
||||
if (nsRefPtr<gfxASurface> maskSurface =
|
||||
GetMaskSurfaceAndTransform(aMaskLayer, &maskTransform)) {
|
||||
AutoMaskData mask;
|
||||
if (GetMaskData(aMaskLayer, &mask)) {
|
||||
if (aOpacity < 1.0) {
|
||||
aContext->PushGroup(gfxASurface::CONTENT_COLOR_ALPHA);
|
||||
aContext->Paint(aOpacity);
|
||||
aContext->PopGroupToSource();
|
||||
}
|
||||
aContext->SetMatrix(maskTransform);
|
||||
aContext->Mask(maskSurface);
|
||||
aContext->SetMatrix(mask.GetTransform());
|
||||
aContext->Mask(mask.GetSurface());
|
||||
return;
|
||||
}
|
||||
|
||||
// if there is no mask, just paint normally
|
||||
aContext->Paint(aOpacity);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
FillWithMask(gfxContext* aContext, float aOpacity, Layer* aMaskLayer)
|
||||
{
|
||||
gfxMatrix maskTransform;
|
||||
if (nsRefPtr<gfxASurface> maskSurface =
|
||||
GetMaskSurfaceAndTransform(aMaskLayer, &maskTransform)) {
|
||||
AutoMaskData mask;
|
||||
if (GetMaskData(aMaskLayer, &mask)) {
|
||||
if (aOpacity < 1.0) {
|
||||
aContext->PushGroup(gfxASurface::CONTENT_COLOR_ALPHA);
|
||||
aContext->FillWithOpacity(aOpacity);
|
||||
aContext->PopGroupToSource();
|
||||
aContext->SetMatrix(maskTransform);
|
||||
aContext->Mask(maskSurface);
|
||||
aContext->SetMatrix(mask.GetTransform());
|
||||
aContext->Mask(mask.GetSurface());
|
||||
} else {
|
||||
aContext->Save();
|
||||
aContext->Clip();
|
||||
aContext->SetMatrix(maskTransform);
|
||||
aContext->Mask(maskSurface);
|
||||
aContext->SetMatrix(mask.GetTransform());
|
||||
aContext->Mask(mask.GetSurface());
|
||||
aContext->NewPath();
|
||||
aContext->Restore();
|
||||
}
|
||||
@ -71,8 +120,8 @@ FillWithMask(gfxContext* aContext, float aOpacity, Layer* aMaskLayer)
|
||||
|
||||
// if there is no mask, just fill normally
|
||||
aContext->FillWithOpacity(aOpacity);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
BasicImplData*
|
||||
ToData(Layer* aLayer)
|
||||
{
|
||||
@ -96,6 +145,6 @@ ShouldShadow(Layer* aLayer)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
#ifndef GFX_BASICLAYERSIMPL_H
|
||||
#define GFX_BASICLAYERSIMPL_H
|
||||
|
||||
#include "ipc/AutoOpenSurface.h"
|
||||
#include "ipc/ShadowLayerChild.h"
|
||||
#include "BasicLayers.h"
|
||||
#include "BasicImplData.h"
|
||||
@ -62,14 +63,58 @@ protected:
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Drawing with a mask requires a mask surface and a transform.
|
||||
* Sometimes the mask surface is a direct gfxASurface, but other times
|
||||
* it's a SurfaceDescriptor. For SurfaceDescriptor, we need to use a
|
||||
* scoped AutoOpenSurface to get a gfxASurface for the
|
||||
* SurfaceDescriptor.
|
||||
*
|
||||
* This helper class manages the gfxASurface-or-SurfaceDescriptor
|
||||
* logic.
|
||||
*/
|
||||
class NS_STACK_CLASS AutoMaskData {
|
||||
public:
|
||||
AutoMaskData() { }
|
||||
~AutoMaskData() { }
|
||||
|
||||
/**
|
||||
* Construct this out of either a gfxASurface or a
|
||||
* SurfaceDescriptor. Construct() must only be called once.
|
||||
* GetSurface() and GetTransform() must not be called until this has
|
||||
* been constructed.
|
||||
*/
|
||||
|
||||
void Construct(const gfxMatrix& aTransform,
|
||||
gfxASurface* aSurface);
|
||||
|
||||
void Construct(const gfxMatrix& aTransform,
|
||||
const SurfaceDescriptor& aSurface);
|
||||
|
||||
/** The returned surface can't escape the scope of |this|. */
|
||||
gfxASurface* GetSurface();
|
||||
const gfxMatrix& GetTransform();
|
||||
|
||||
private:
|
||||
bool IsConstructed();
|
||||
|
||||
gfxMatrix mTransform;
|
||||
nsRefPtr<gfxASurface> mSurface;
|
||||
Maybe<AutoOpenSurface> mSurfaceOpener;
|
||||
|
||||
AutoMaskData(const AutoMaskData&) MOZ_DELETE;
|
||||
AutoMaskData& operator=(const AutoMaskData&) MOZ_DELETE;
|
||||
};
|
||||
|
||||
/*
|
||||
* Extract a mask surface for a mask layer
|
||||
* Returns a surface for the mask layer if a mask layer is present and has a
|
||||
* valid surface and transform; nsnull otherwise.
|
||||
* The transform for the layer will be put in aMaskTransform
|
||||
* Returns true and through outparams a surface for the mask layer if
|
||||
* a mask layer is present and has a valid surface and transform;
|
||||
* false otherwise.
|
||||
* The transform for the layer will be put in aMaskData
|
||||
*/
|
||||
already_AddRefed<gfxASurface>
|
||||
GetMaskSurfaceAndTransform(Layer* aMaskLayer, gfxMatrix* aMaskTransform);
|
||||
bool
|
||||
GetMaskData(Layer* aMaskLayer, AutoMaskData* aMaskData);
|
||||
|
||||
// Paint the current source to a context using a mask, if present
|
||||
void
|
||||
@ -117,7 +162,7 @@ MaybeCreateShadowFor(BasicShadowableLayer* aLayer,
|
||||
aLayer->SetShadow(shadow);
|
||||
(aMgr->*aMethod)(aLayer);
|
||||
aMgr->Hold(aLayer->AsLayer());
|
||||
}
|
||||
}
|
||||
|
||||
#define MAYBE_CREATE_SHADOW(_type) \
|
||||
MaybeCreateShadowFor(layer, this, \
|
||||
|
@ -228,6 +228,58 @@ BasicThebesLayer::PaintThebes(gfxContext* aContext,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* AutoOpenBuffer is a helper that builds on top of AutoOpenSurface,
|
||||
* which we need to get a gfxASurface from a SurfaceDescriptor. For
|
||||
* other layer types, simple lexical scoping of AutoOpenSurface is
|
||||
* easy. For ThebesLayers, the lifetime of buffer mappings doesn't
|
||||
* exactly match simple lexical scopes, so naively putting
|
||||
* AutoOpenSurfaces on the stack doesn't always work. We use this
|
||||
* helper to track openings instead.
|
||||
*
|
||||
* Any surface that's opened while painting this ThebesLayer will
|
||||
* notify this helper and register itself for unmapping.
|
||||
*
|
||||
* We ignore buffer destruction here because the shadow layers
|
||||
* protocol already ensures that destroyed buffers stay alive until
|
||||
* end-of-transaction.
|
||||
*/
|
||||
struct NS_STACK_CLASS AutoBufferTracker {
|
||||
AutoBufferTracker(BasicShadowableThebesLayer* aLayer)
|
||||
: mLayer(aLayer)
|
||||
{
|
||||
MOZ_ASSERT(!mLayer->mBufferTracker);
|
||||
|
||||
mLayer->mBufferTracker = this;
|
||||
if (IsSurfaceDescriptorValid(mLayer->mBackBuffer)) {
|
||||
mInitialBuffer.construct(OPEN_READ_WRITE, mLayer->mBackBuffer);
|
||||
mLayer->mBuffer.MapBuffer(mInitialBuffer.ref().Get());
|
||||
}
|
||||
}
|
||||
|
||||
~AutoBufferTracker() {
|
||||
mLayer->mBufferTracker = nsnull;
|
||||
mLayer->mBuffer.UnmapBuffer();
|
||||
// mInitialBuffer and mNewBuffer will clean up after themselves if
|
||||
// they were constructed.
|
||||
}
|
||||
|
||||
gfxASurface*
|
||||
CreatedBuffer(const SurfaceDescriptor& aDescriptor) {
|
||||
Maybe<AutoOpenSurface>* surface = mNewBuffers.AppendElement();
|
||||
surface->construct(OPEN_READ_WRITE, aDescriptor);
|
||||
return surface->ref().Get();
|
||||
}
|
||||
|
||||
Maybe<AutoOpenSurface> mInitialBuffer;
|
||||
nsAutoTArray<Maybe<AutoOpenSurface>, 2> mNewBuffers;
|
||||
BasicShadowableThebesLayer* mLayer;
|
||||
|
||||
private:
|
||||
AutoBufferTracker(const AutoBufferTracker&) MOZ_DELETE;
|
||||
AutoBufferTracker& operator=(const AutoBufferTracker&) MOZ_DELETE;
|
||||
};
|
||||
|
||||
void
|
||||
BasicShadowableThebesLayer::PaintThebes(gfxContext* aContext,
|
||||
Layer* aMaskLayer,
|
||||
@ -240,6 +292,8 @@ BasicShadowableThebesLayer::PaintThebes(gfxContext* aContext,
|
||||
return;
|
||||
}
|
||||
|
||||
AutoBufferTracker tracker(this);
|
||||
|
||||
BasicThebesLayer::PaintThebes(aContext, nsnull, aCallback, aCallbackData, aReadback);
|
||||
if (aMaskLayer) {
|
||||
static_cast<BasicImplData*>(aMaskLayer->ImplData())
|
||||
@ -280,18 +334,22 @@ BasicShadowableThebesLayer::SyncFrontBufferToBackBuffer()
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<gfxASurface> backBuffer;
|
||||
gfxASurface* backBuffer = mBuffer.GetBuffer();
|
||||
if (!IsSurfaceDescriptorValid(mBackBuffer)) {
|
||||
NS_ABORT_IF_FALSE(mROFrontBuffer.type() == OptionalThebesBuffer::TThebesBuffer,
|
||||
"should have a front RO buffer by now");
|
||||
MOZ_ASSERT(!backBuffer);
|
||||
MOZ_ASSERT(mROFrontBuffer.type() == OptionalThebesBuffer::TThebesBuffer);
|
||||
const ThebesBuffer roFront = mROFrontBuffer.get_ThebesBuffer();
|
||||
nsRefPtr<gfxASurface> roFrontBuffer = BasicManager()->OpenDescriptor(roFront.buffer());
|
||||
backBuffer = CreateBuffer(roFrontBuffer->GetContentType(), roFrontBuffer->GetSize());
|
||||
} else {
|
||||
backBuffer = BasicManager()->OpenDescriptor(mBackBuffer);
|
||||
AutoOpenSurface roFrontBuffer(OPEN_READ_ONLY, roFront.buffer());
|
||||
AllocBackBuffer(roFrontBuffer.ContentType(), roFrontBuffer.Size());
|
||||
}
|
||||
mFrontAndBackBufferDiffer = false;
|
||||
|
||||
Maybe<AutoOpenSurface> autoBackBuffer;
|
||||
if (!backBuffer) {
|
||||
autoBackBuffer.construct(OPEN_READ_WRITE, mBackBuffer);
|
||||
backBuffer = autoBackBuffer.ref().Get();
|
||||
}
|
||||
|
||||
if (OptionalThebesBuffer::Tnull_t == mROFrontBuffer.type()) {
|
||||
// We didn't get back a read-only ref to our old back buffer (the
|
||||
// parent's new front buffer). If the parent is pushing updates
|
||||
@ -310,10 +368,10 @@ BasicShadowableThebesLayer::SyncFrontBufferToBackBuffer()
|
||||
mFrontUpdatedRegion.GetBounds().height));
|
||||
|
||||
const ThebesBuffer roFront = mROFrontBuffer.get_ThebesBuffer();
|
||||
nsRefPtr<gfxASurface> roFrontBuffer = BasicManager()->OpenDescriptor(roFront.buffer());
|
||||
AutoOpenSurface autoROFront(OPEN_READ_ONLY, roFront.buffer());
|
||||
mBuffer.SetBackingBufferAndUpdateFrom(
|
||||
backBuffer,
|
||||
roFrontBuffer, roFront.rect(), roFront.rotation(),
|
||||
autoROFront.Get(), roFront.rect(), roFront.rotation(),
|
||||
mFrontUpdatedRegion);
|
||||
mIsNewBuffer = false;
|
||||
// Now the new back buffer has the same (interesting) pixels as the
|
||||
@ -364,6 +422,23 @@ BasicShadowableThebesLayer::PaintBuffer(gfxContext* aContext,
|
||||
mBackBuffer);
|
||||
}
|
||||
|
||||
void
|
||||
BasicShadowableThebesLayer::AllocBackBuffer(Buffer::ContentType aType,
|
||||
const nsIntSize& aSize)
|
||||
{
|
||||
// This function may *not* open the buffer it allocates.
|
||||
if (!BasicManager()->AllocBuffer(gfxIntSize(aSize.width, aSize.height),
|
||||
aType,
|
||||
&mBackBuffer)) {
|
||||
enum { buflen = 256 };
|
||||
char buf[buflen];
|
||||
PR_snprintf(buf, buflen,
|
||||
"creating ThebesLayer 'back buffer' failed! width=%d, height=%d, type=%x",
|
||||
aSize.width, aSize.height, int(aType));
|
||||
NS_RUNTIMEABORT(buf);
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<gfxASurface>
|
||||
BasicShadowableThebesLayer::CreateBuffer(Buffer::ContentType aType,
|
||||
const nsIntSize& aSize)
|
||||
@ -382,24 +457,15 @@ BasicShadowableThebesLayer::CreateBuffer(Buffer::ContentType aType,
|
||||
mBackBuffer = SurfaceDescriptor();
|
||||
}
|
||||
|
||||
// XXX error handling
|
||||
if (!BasicManager()->AllocBuffer(gfxIntSize(aSize.width, aSize.height),
|
||||
aType,
|
||||
&mBackBuffer)) {
|
||||
enum { buflen = 256 };
|
||||
char buf[buflen];
|
||||
PR_snprintf(buf, buflen,
|
||||
"creating ThebesLayer 'back buffer' failed! width=%d, height=%d, type=%x",
|
||||
aSize.width, aSize.height, int(aType));
|
||||
NS_RUNTIMEABORT(buf);
|
||||
}
|
||||
AllocBackBuffer(aType, aSize);
|
||||
|
||||
NS_ABORT_IF_FALSE(!mIsNewBuffer,
|
||||
"Bad! Did we create a buffer twice without painting?");
|
||||
|
||||
mIsNewBuffer = true;
|
||||
|
||||
return BasicManager()->OpenDescriptor(mBackBuffer);
|
||||
nsRefPtr<gfxASurface> buffer = mBufferTracker->CreatedBuffer(mBackBuffer);
|
||||
return buffer.forget();
|
||||
}
|
||||
|
||||
void
|
||||
@ -483,12 +549,10 @@ BasicShadowThebesLayer::Swap(const ThebesBuffer& aNewFront,
|
||||
OptionalThebesBuffer* aReadOnlyFront,
|
||||
nsIntRegion* aFrontUpdatedRegion)
|
||||
{
|
||||
nsRefPtr<gfxASurface> newFrontBuffer =
|
||||
BasicManager()->OpenDescriptor(aNewFront.buffer());
|
||||
|
||||
if (IsSurfaceDescriptorValid(mFrontBufferDescriptor)) {
|
||||
nsRefPtr<gfxASurface> currentFront = BasicManager()->OpenDescriptor(mFrontBufferDescriptor);
|
||||
if (currentFront->GetSize() != newFrontBuffer->GetSize()) {
|
||||
AutoOpenSurface autoNewFrontBuffer(OPEN_READ_ONLY, aNewFront.buffer());
|
||||
AutoOpenSurface autoCurrentFront(OPEN_READ_ONLY, mFrontBufferDescriptor);
|
||||
if (autoCurrentFront.Size() != autoNewFrontBuffer.Size()) {
|
||||
// Current front buffer is obsolete
|
||||
DestroyFrontBuffer();
|
||||
}
|
||||
@ -504,12 +568,11 @@ BasicShadowThebesLayer::Swap(const ThebesBuffer& aNewFront,
|
||||
// They might overlap with our old pixels.
|
||||
aNewBackValidRegion->Sub(mOldValidRegion, aUpdatedRegion);
|
||||
|
||||
nsRefPtr<gfxASurface> unused;
|
||||
nsIntRect backRect;
|
||||
nsIntPoint backRotation;
|
||||
mFrontBuffer.Swap(
|
||||
newFrontBuffer, aNewFront.rect(), aNewFront.rotation(),
|
||||
getter_AddRefs(unused), &backRect, &backRotation);
|
||||
aNewFront.rect(), aNewFront.rotation(),
|
||||
&backRect, &backRotation);
|
||||
|
||||
if (aNewBack->type() != OptionalThebesBuffer::Tnull_t) {
|
||||
aNewBack->get_ThebesBuffer().rect() = backRect;
|
||||
@ -534,11 +597,16 @@ BasicShadowThebesLayer::PaintThebes(gfxContext* aContext,
|
||||
NS_ASSERTION(BasicManager()->IsRetained(),
|
||||
"ShadowThebesLayer makes no sense without retained mode");
|
||||
|
||||
if (!mFrontBuffer.GetBuffer()) {
|
||||
if (!IsSurfaceDescriptorValid(mFrontBufferDescriptor)) {
|
||||
return;
|
||||
}
|
||||
|
||||
AutoOpenSurface autoFrontBuffer(OPEN_READ_ONLY, mFrontBufferDescriptor);
|
||||
mFrontBuffer.MapBuffer(autoFrontBuffer.Get());
|
||||
|
||||
mFrontBuffer.DrawTo(this, aContext, GetEffectiveOpacity(), aMaskLayer);
|
||||
|
||||
mFrontBuffer.UnmapBuffer();
|
||||
}
|
||||
|
||||
already_AddRefed<ThebesLayer>
|
||||
|
@ -103,14 +103,19 @@ protected:
|
||||
Buffer mBuffer;
|
||||
};
|
||||
|
||||
struct AutoBufferTracker;
|
||||
|
||||
class BasicShadowableThebesLayer : public BasicThebesLayer,
|
||||
public BasicShadowableLayer
|
||||
{
|
||||
friend struct AutoBufferTracker;
|
||||
|
||||
typedef BasicThebesLayer Base;
|
||||
|
||||
public:
|
||||
BasicShadowableThebesLayer(BasicShadowLayerManager* aManager)
|
||||
: BasicThebesLayer(aManager)
|
||||
, mBufferTracker(nsnull)
|
||||
, mIsNewBuffer(false)
|
||||
, mFrontAndBackBufferDiffer(false)
|
||||
{
|
||||
@ -163,6 +168,10 @@ private:
|
||||
LayerManager::DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData) MOZ_OVERRIDE;
|
||||
|
||||
// This function may *not* open the buffer it allocates.
|
||||
void
|
||||
AllocBackBuffer(Buffer::ContentType aType, const nsIntSize& aSize);
|
||||
|
||||
virtual already_AddRefed<gfxASurface>
|
||||
CreateBuffer(Buffer::ContentType aType, const nsIntSize& aSize) MOZ_OVERRIDE;
|
||||
|
||||
@ -180,6 +189,12 @@ private:
|
||||
nsIntRect mBackBufferRect;
|
||||
nsIntPoint mBackBufferRectRotation;
|
||||
|
||||
// This helper object lives on the stack during its lifetime and
|
||||
// keeps track of buffers we might have mapped and/or allocated.
|
||||
// When it goes out of scope on the stack, it unmaps whichever
|
||||
// buffers have been mapped (if any).
|
||||
AutoBufferTracker* mBufferTracker;
|
||||
|
||||
bool mIsNewBuffer;
|
||||
OptionalThebesBuffer mROFrontBuffer;
|
||||
nsIntRegion mFrontUpdatedRegion;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user