mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 19:35:51 +00:00
Merge inbound to mozilla-central. a=merge
This commit is contained in:
commit
db79375c66
@ -47,6 +47,7 @@ AccessibleNode::AccessibleNode(nsINode* aNode) :
|
||||
mIntProperties(3),
|
||||
mUIntProperties(6),
|
||||
mBooleanProperties(0),
|
||||
mRelationProperties(3),
|
||||
mStringProperties(16),
|
||||
mDOMNode(aNode)
|
||||
{
|
||||
|
@ -51,6 +51,17 @@ struct ParentObject;
|
||||
SetProperty(AOMStringProperty::e##name, a##name); \
|
||||
} \
|
||||
|
||||
#define ANODE_RELATION_FUNC(name) \
|
||||
already_AddRefed<AccessibleNode> Get##name() \
|
||||
{ \
|
||||
return GetProperty(AOMRelationProperty::e##name); \
|
||||
} \
|
||||
\
|
||||
void Set##name(AccessibleNode* a##name) \
|
||||
{ \
|
||||
SetProperty(AOMRelationProperty::e##name, a##name); \
|
||||
} \
|
||||
|
||||
#define ANODE_PROPS(typeName, type, ...) \
|
||||
enum class AOM##typeName##Property { \
|
||||
MOZ_FOR_EACH(ANODE_ENUM, (), (__VA_ARGS__)) \
|
||||
@ -63,6 +74,12 @@ struct ParentObject;
|
||||
}; \
|
||||
MOZ_FOR_EACH(ANODE_STRING_FUNC, (), (__VA_ARGS__)) \
|
||||
|
||||
#define ANODE_RELATION_PROPS(...) \
|
||||
enum class AOMRelationProperty { \
|
||||
MOZ_FOR_EACH(ANODE_ENUM, (), (__VA_ARGS__)) \
|
||||
}; \
|
||||
MOZ_FOR_EACH(ANODE_RELATION_FUNC, (), (__VA_ARGS__)) \
|
||||
|
||||
#define ANODE_ACCESSOR_MUTATOR(typeName, type, defVal) \
|
||||
nsDataHashtable<nsUint32HashKey, type> m##typeName##Properties; \
|
||||
\
|
||||
@ -164,6 +181,12 @@ public:
|
||||
ValueNow
|
||||
)
|
||||
|
||||
ANODE_RELATION_PROPS(
|
||||
ActiveDescendant,
|
||||
Details,
|
||||
ErrorMessage
|
||||
)
|
||||
|
||||
protected:
|
||||
AccessibleNode(const AccessibleNode& aCopy) = delete;
|
||||
AccessibleNode& operator=(const AccessibleNode& aCopy) = delete;
|
||||
@ -213,9 +236,29 @@ protected:
|
||||
ANODE_ACCESSOR_MUTATOR(Int, int32_t, 0)
|
||||
ANODE_ACCESSOR_MUTATOR(UInt, uint32_t, 0)
|
||||
|
||||
already_AddRefed<AccessibleNode> GetProperty(AOMRelationProperty aProperty)
|
||||
{
|
||||
RefPtr<AccessibleNode> data;
|
||||
if (mRelationProperties.Get(static_cast<int>(aProperty), &data)) {
|
||||
return data.forget();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void SetProperty(AOMRelationProperty aProperty,
|
||||
AccessibleNode* aValue)
|
||||
{
|
||||
if (!aValue) {
|
||||
mRelationProperties.Remove(static_cast<int>(aProperty));
|
||||
} else {
|
||||
mRelationProperties.Put(static_cast<int>(aProperty), aValue);
|
||||
}
|
||||
}
|
||||
|
||||
// The 2k'th bit indicates whether the k'th boolean property is used(1) or not(0)
|
||||
// and 2k+1'th bit contains the property's value(1:true, 0:false)
|
||||
uint32_t mBooleanProperties;
|
||||
nsDataHashtable<nsUint32HashKey, RefPtr<AccessibleNode> > mRelationProperties;
|
||||
nsDataHashtable<nsUint32HashKey, nsString> mStringProperties;
|
||||
|
||||
RefPtr<a11y::Accessible> mIntl;
|
||||
|
@ -29,6 +29,13 @@ const GECKOVIEW_MESSAGE = {
|
||||
CLIPBOARD: "GeckoView:AccessibilityClipboard",
|
||||
};
|
||||
|
||||
const ACCESSFU_MESSAGE = {
|
||||
PRESENT: "AccessFu:Present",
|
||||
DOSCROLL: "AccessFu:DoScroll",
|
||||
};
|
||||
|
||||
const FRAME_SCRIPT = "chrome://global/content/accessibility/content-script.js";
|
||||
|
||||
var AccessFu = {
|
||||
/**
|
||||
* A lazy getter for event handler that binds the scope to AccessFu object.
|
||||
@ -64,11 +71,6 @@ var AccessFu = {
|
||||
this._attachWindow(windows.getNext());
|
||||
}
|
||||
|
||||
if (this.readyCallback) {
|
||||
this.readyCallback();
|
||||
delete this.readyCallback;
|
||||
}
|
||||
|
||||
Logger.info("AccessFu:Enabled");
|
||||
},
|
||||
|
||||
@ -107,17 +109,10 @@ var AccessFu = {
|
||||
});
|
||||
|
||||
switch (aMessage.name) {
|
||||
case "AccessFu:Ready":
|
||||
let mm = Utils.getMessageManager(aMessage.target);
|
||||
if (this._enabled) {
|
||||
mm.sendAsyncMessage("AccessFu:Start",
|
||||
{method: "start", buildApp: Utils.MozBuildApp});
|
||||
}
|
||||
break;
|
||||
case "AccessFu:Present":
|
||||
case ACCESSFU_MESSAGE.PRESENT:
|
||||
this._output(aMessage.json, aMessage.target);
|
||||
break;
|
||||
case "AccessFu:DoScroll":
|
||||
case ACCESSFU_MESSAGE.DOSCROLL:
|
||||
this.Input.doScroll(aMessage.json, aMessage.target);
|
||||
break;
|
||||
}
|
||||
@ -130,13 +125,13 @@ var AccessFu = {
|
||||
return;
|
||||
}
|
||||
|
||||
for (let mm of Utils.getAllMessageManagers(win)) {
|
||||
this._addMessageListeners(mm);
|
||||
this._loadFrameScript(mm);
|
||||
// Set up frame script
|
||||
let mm = win.messageManager;
|
||||
for (let messageName of Object.values(ACCESSFU_MESSAGE)) {
|
||||
mm.addMessageListener(messageName, this);
|
||||
}
|
||||
mm.loadFrameScript(FRAME_SCRIPT, true);
|
||||
|
||||
win.addEventListener("TabOpen", this);
|
||||
win.addEventListener("TabClose", this);
|
||||
win.addEventListener("TabSelect", this);
|
||||
if (win.WindowEventDispatcher) {
|
||||
// desktop mochitests don't have this.
|
||||
@ -146,13 +141,13 @@ var AccessFu = {
|
||||
},
|
||||
|
||||
_detachWindow: function _detachWindow(win) {
|
||||
for (let mm of Utils.getAllMessageManagers(win)) {
|
||||
mm.sendAsyncMessage("AccessFu:Stop");
|
||||
this._removeMessageListeners(mm);
|
||||
let mm = win.messageManager;
|
||||
mm.broadcastAsyncMessage("AccessFu:Stop");
|
||||
mm.removeDelayedFrameScript(FRAME_SCRIPT);
|
||||
for (let messageName of Object.values(ACCESSFU_MESSAGE)) {
|
||||
mm.removeMessageListener(messageName, this);
|
||||
}
|
||||
|
||||
win.removeEventListener("TabOpen", this);
|
||||
win.removeEventListener("TabClose", this);
|
||||
win.removeEventListener("TabSelect", this);
|
||||
if (win.WindowEventDispatcher) {
|
||||
// desktop mochitests don't have this.
|
||||
@ -193,38 +188,6 @@ var AccessFu = {
|
||||
}
|
||||
},
|
||||
|
||||
_loadFrameScript: function _loadFrameScript(aMessageManager) {
|
||||
if (!this._processedMessageManagers.includes(aMessageManager)) {
|
||||
aMessageManager.loadFrameScript(
|
||||
"chrome://global/content/accessibility/content-script.js", true);
|
||||
this._processedMessageManagers.push(aMessageManager);
|
||||
} else if (this._enabled) {
|
||||
// If the content-script is already loaded and AccessFu is enabled,
|
||||
// send an AccessFu:Start message.
|
||||
aMessageManager.sendAsyncMessage("AccessFu:Start",
|
||||
{method: "start", buildApp: Utils.MozBuildApp});
|
||||
}
|
||||
},
|
||||
|
||||
_addMessageListeners: function _addMessageListeners(aMessageManager) {
|
||||
aMessageManager.addMessageListener("AccessFu:Present", this);
|
||||
aMessageManager.addMessageListener("AccessFu:Ready", this);
|
||||
aMessageManager.addMessageListener("AccessFu:DoScroll", this);
|
||||
},
|
||||
|
||||
_removeMessageListeners: function _removeMessageListeners(aMessageManager) {
|
||||
aMessageManager.removeMessageListener("AccessFu:Present", this);
|
||||
aMessageManager.removeMessageListener("AccessFu:Ready", this);
|
||||
aMessageManager.removeMessageListener("AccessFu:DoScroll", this);
|
||||
},
|
||||
|
||||
_handleMessageManager: function _handleMessageManager(aMessageManager) {
|
||||
if (this._enabled) {
|
||||
this._addMessageListeners(aMessageManager);
|
||||
}
|
||||
this._loadFrameScript(aMessageManager);
|
||||
},
|
||||
|
||||
onEvent(event, data, callback) {
|
||||
switch (event) {
|
||||
case GECKOVIEW_MESSAGE.SETTINGS:
|
||||
@ -280,19 +243,11 @@ var AccessFu = {
|
||||
|
||||
observe: function observe(aSubject, aTopic, aData) {
|
||||
switch (aTopic) {
|
||||
case "remote-browser-shown":
|
||||
case "inprocess-browser-shown":
|
||||
{
|
||||
// Ignore notifications that aren't from a Browser
|
||||
let frameLoader = aSubject;
|
||||
if (!frameLoader.ownerIsMozBrowserFrame) {
|
||||
return;
|
||||
}
|
||||
this._handleMessageManager(frameLoader.messageManager);
|
||||
break;
|
||||
}
|
||||
case "domwindowopened": {
|
||||
this._attachWindow(aSubject.QueryInterface(Ci.nsIDOMWindow));
|
||||
let win = aSubject.QueryInterface(Ci.nsIDOMWindow);
|
||||
win.addEventListener("load", () => {
|
||||
this._attachWindow(win);
|
||||
}, { once: true });
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -300,22 +255,6 @@ var AccessFu = {
|
||||
|
||||
_handleEvent: function _handleEvent(aEvent) {
|
||||
switch (aEvent.type) {
|
||||
case "TabOpen":
|
||||
{
|
||||
let mm = Utils.getMessageManager(aEvent.target);
|
||||
this._handleMessageManager(mm);
|
||||
break;
|
||||
}
|
||||
case "TabClose":
|
||||
{
|
||||
let mm = Utils.getMessageManager(aEvent.target);
|
||||
let mmIndex = this._processedMessageManagers.indexOf(mm);
|
||||
if (mmIndex > -1) {
|
||||
this._removeMessageListeners(mm);
|
||||
this._processedMessageManagers.splice(mmIndex, 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "TabSelect":
|
||||
{
|
||||
if (this._focused) {
|
||||
@ -350,10 +289,6 @@ var AccessFu = {
|
||||
// Layerview is focused
|
||||
_focused: false,
|
||||
|
||||
// Keep track of message managers tha already have a 'content-script.js'
|
||||
// injected.
|
||||
_processedMessageManagers: [],
|
||||
|
||||
/**
|
||||
* Adjusts the given bounds that are defined in device display pixels
|
||||
* to client-relative CSS pixels of the chrome window.
|
||||
@ -413,18 +348,6 @@ var Input = {
|
||||
mm.sendAsyncMessage("AccessFu:Activate", { offset: 0 });
|
||||
},
|
||||
|
||||
// XXX: This is here for backwards compatability with screen reader simulator
|
||||
// it should be removed when the extension is updated on amo.
|
||||
scroll: function scroll(aPage, aHorizontal) {
|
||||
this.sendScrollMessage(aPage, aHorizontal);
|
||||
},
|
||||
|
||||
sendScrollMessage: function sendScrollMessage(aPage, aHorizontal) {
|
||||
const mm = Utils.getMessageManager();
|
||||
mm.sendAsyncMessage("AccessFu:Scroll",
|
||||
{page: aPage, horizontal: aHorizontal, origin: "top"});
|
||||
},
|
||||
|
||||
doScroll: function doScroll(aDetails, aBrowser) {
|
||||
let horizontal = aDetails.horizontal;
|
||||
let page = aDetails.page;
|
||||
|
@ -25,9 +25,8 @@ ChromeUtils.defineModuleGetter(this, "setTimeout",
|
||||
|
||||
var EXPORTED_SYMBOLS = ["EventManager"];
|
||||
|
||||
function EventManager(aContentScope, aContentControl) {
|
||||
function EventManager(aContentScope) {
|
||||
this.contentScope = aContentScope;
|
||||
this.contentControl = aContentControl;
|
||||
this.addEventListener = this.contentScope.addEventListener.bind(
|
||||
this.contentScope);
|
||||
this.removeEventListener = this.contentScope.removeEventListener.bind(
|
||||
@ -85,6 +84,10 @@ this.EventManager.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
get contentControl() {
|
||||
return this.contentScope._jsat_contentControl;
|
||||
},
|
||||
|
||||
handleEvent: function handleEvent(aEvent) {
|
||||
Logger.debug(() => {
|
||||
return ["DOMEvent", aEvent.type];
|
||||
@ -247,7 +250,7 @@ this.EventManager.prototype = {
|
||||
|
||||
this.present(Presentation.focused(acc));
|
||||
|
||||
if (this.inTest) {
|
||||
if (Utils.inTest) {
|
||||
this.sendMsgFunc("AccessFu:Focused");
|
||||
}
|
||||
break;
|
||||
|
@ -82,41 +82,6 @@ var Utils = { // jshint ignore:line
|
||||
return win.document.querySelector("browser[type=content][primary=true]");
|
||||
},
|
||||
|
||||
getAllMessageManagers: function getAllMessageManagers(aWindow) {
|
||||
let messageManagers = new Set();
|
||||
|
||||
function collectLeafMessageManagers(mm) {
|
||||
for (let i = 0; i < mm.childCount; i++) {
|
||||
let childMM = mm.getChildAt(i);
|
||||
|
||||
if ("sendAsyncMessage" in childMM) {
|
||||
messageManagers.add(childMM);
|
||||
} else {
|
||||
collectLeafMessageManagers(childMM);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
collectLeafMessageManagers(aWindow.messageManager);
|
||||
|
||||
let browser = this.getCurrentBrowser(aWindow);
|
||||
let document = browser ? browser.contentDocument : null;
|
||||
|
||||
if (document) {
|
||||
let remoteframes = document.querySelectorAll("iframe");
|
||||
|
||||
for (let i = 0; i < remoteframes.length; ++i) {
|
||||
let mm = this.getMessageManager(remoteframes[i]);
|
||||
if (mm) {
|
||||
messageManagers.add(mm);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return messageManagers;
|
||||
},
|
||||
|
||||
get isContentProcess() {
|
||||
delete this.isContentProcess;
|
||||
this.isContentProcess =
|
||||
@ -418,7 +383,8 @@ var Logger = { // jshint ignore:line
|
||||
|
||||
logLevel: 1, // INFO;
|
||||
|
||||
test: false,
|
||||
// Note: used for testing purposes. If true, also log to the console service.
|
||||
useConsoleService: false,
|
||||
|
||||
log: function log(aLogLevel) {
|
||||
if (aLogLevel < this.logLevel) {
|
||||
@ -430,9 +396,7 @@ var Logger = { // jshint ignore:line
|
||||
message = "[" + Utils.ScriptName + "] " + this._LEVEL_NAMES[aLogLevel + 1] +
|
||||
" " + message + "\n";
|
||||
dump(message);
|
||||
// Note: used for testing purposes. If |this.test| is true, also log to
|
||||
// the console service.
|
||||
if (this.test) {
|
||||
if (this.useConsoleService) {
|
||||
try {
|
||||
Services.console.logStringMessage(message);
|
||||
} catch (ex) {
|
||||
|
@ -6,129 +6,49 @@
|
||||
|
||||
ChromeUtils.defineModuleGetter(this, "Logger",
|
||||
"resource://gre/modules/accessibility/Utils.jsm");
|
||||
ChromeUtils.defineModuleGetter(this, "Presentation",
|
||||
"resource://gre/modules/accessibility/Presentation.jsm");
|
||||
ChromeUtils.defineModuleGetter(this, "Utils",
|
||||
"resource://gre/modules/accessibility/Utils.jsm");
|
||||
ChromeUtils.defineModuleGetter(this, "EventManager",
|
||||
"resource://gre/modules/accessibility/EventManager.jsm");
|
||||
ChromeUtils.defineModuleGetter(this, "ContentControl",
|
||||
"resource://gre/modules/accessibility/ContentControl.jsm");
|
||||
ChromeUtils.defineModuleGetter(this, "Roles",
|
||||
"resource://gre/modules/accessibility/Constants.jsm");
|
||||
ChromeUtils.defineModuleGetter(this, "States",
|
||||
"resource://gre/modules/accessibility/Constants.jsm");
|
||||
|
||||
Logger.info("content-script.js", content.document.location);
|
||||
|
||||
var eventManager = null;
|
||||
var contentControl = null;
|
||||
function onStop(m) {
|
||||
Logger.debug("AccessFu:Stop");
|
||||
|
||||
function forwardToParent(aMessage) {
|
||||
// XXX: This is a silly way to make a deep copy
|
||||
let newJSON = JSON.parse(JSON.stringify(aMessage.json));
|
||||
newJSON.origin = "child";
|
||||
sendAsyncMessage(aMessage.name, newJSON);
|
||||
removeMessageListener("AccessFu:Stop", onStop);
|
||||
|
||||
this._jsat_eventManager.stop();
|
||||
this._jsat_contentControl.stop();
|
||||
}
|
||||
|
||||
function forwardToChild(aMessage, aListener, aVCPosition) {
|
||||
let acc = aVCPosition || Utils.getVirtualCursor(content.document).position;
|
||||
addMessageListener("AccessFu:Stop", onStop);
|
||||
|
||||
if (!Utils.isAliveAndVisible(acc) || acc.role != Roles.INTERNAL_FRAME) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Logger.debug(() => {
|
||||
return ["forwardToChild", Logger.accessibleToString(acc),
|
||||
aMessage.name, JSON.stringify(aMessage.json, null, " ")];
|
||||
});
|
||||
|
||||
let mm = Utils.getMessageManager(acc.DOMNode);
|
||||
|
||||
if (aListener) {
|
||||
mm.addMessageListener(aMessage.name, aListener);
|
||||
}
|
||||
|
||||
// XXX: This is a silly way to make a deep copy
|
||||
let newJSON = JSON.parse(JSON.stringify(aMessage.json));
|
||||
newJSON.origin = "parent";
|
||||
if (Utils.isContentProcess) {
|
||||
// XXX: OOP content's screen offset is 0,
|
||||
// so we remove the real screen offset here.
|
||||
newJSON.x -= content.mozInnerScreenX;
|
||||
newJSON.y -= content.mozInnerScreenY;
|
||||
}
|
||||
mm.sendAsyncMessage(aMessage.name, newJSON);
|
||||
return true;
|
||||
if (!this._jsat_contentControl) {
|
||||
this._jsat_contentControl = new ContentControl(this);
|
||||
}
|
||||
this._jsat_contentControl.start();
|
||||
|
||||
function presentCaretChange(aText, aOldOffset, aNewOffset) {
|
||||
if (aOldOffset !== aNewOffset) {
|
||||
let msg = Presentation.textSelectionChanged(aText, aNewOffset, aNewOffset,
|
||||
aOldOffset, aOldOffset, true);
|
||||
sendAsyncMessage("AccessFu:Present", msg);
|
||||
if (!this._jsat_eventManager) {
|
||||
this._jsat_eventManager = new EventManager(this);
|
||||
}
|
||||
this._jsat_eventManager.start();
|
||||
|
||||
function contentStarted() {
|
||||
let accDoc = Utils.AccService.getAccessibleFor(content.document);
|
||||
if (accDoc && !Utils.getState(accDoc).contains(States.BUSY)) {
|
||||
sendAsyncMessage("AccessFu:ContentStarted");
|
||||
} else {
|
||||
content.setTimeout(contentStarted, 0);
|
||||
}
|
||||
}
|
||||
|
||||
function scroll(aMessage) {
|
||||
let position = Utils.getVirtualCursor(content.document).position;
|
||||
if (!forwardToChild(aMessage, scroll, position)) {
|
||||
sendAsyncMessage("AccessFu:DoScroll",
|
||||
{ bounds: Utils.getBounds(position),
|
||||
page: aMessage.json.page,
|
||||
horizontal: aMessage.json.horizontal });
|
||||
}
|
||||
if (Utils.inTest) {
|
||||
// During a test we want to wait for the document to finish loading for
|
||||
// consistency.
|
||||
contentStarted();
|
||||
}
|
||||
|
||||
addMessageListener(
|
||||
"AccessFu:Start",
|
||||
function(m) {
|
||||
if (m.json.logLevel) {
|
||||
Logger.logLevel = Logger[m.json.logLevel];
|
||||
}
|
||||
|
||||
Logger.debug("AccessFu:Start");
|
||||
if (m.json.buildApp)
|
||||
Utils.MozBuildApp = m.json.buildApp;
|
||||
|
||||
addMessageListener("AccessFu:Scroll", scroll);
|
||||
|
||||
if (!contentControl) {
|
||||
contentControl = new ContentControl(this);
|
||||
}
|
||||
contentControl.start();
|
||||
|
||||
if (!eventManager) {
|
||||
eventManager = new EventManager(this, contentControl);
|
||||
}
|
||||
eventManager.inTest = m.json.inTest;
|
||||
eventManager.start();
|
||||
|
||||
function contentStarted() {
|
||||
let accDoc = Utils.AccService.getAccessibleFor(content.document);
|
||||
if (accDoc && !Utils.getState(accDoc).contains(States.BUSY)) {
|
||||
sendAsyncMessage("AccessFu:ContentStarted");
|
||||
} else {
|
||||
content.setTimeout(contentStarted, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (m.json.inTest) {
|
||||
// During a test we want to wait for the document to finish loading for
|
||||
// consistency.
|
||||
contentStarted();
|
||||
}
|
||||
});
|
||||
|
||||
addMessageListener(
|
||||
"AccessFu:Stop",
|
||||
function(m) {
|
||||
Logger.debug("AccessFu:Stop");
|
||||
|
||||
removeMessageListener("AccessFu:Scroll", scroll);
|
||||
|
||||
eventManager.stop();
|
||||
contentControl.stop();
|
||||
});
|
||||
|
||||
sendAsyncMessage("AccessFu:Ready");
|
||||
|
@ -84,6 +84,13 @@
|
||||
is(anode[prop], null, `anode.${prop} was assigned null`);
|
||||
}
|
||||
|
||||
function testRelationProp(anode, node, prop) {
|
||||
is(anode[prop], null, `anode.${prop} should be null`);
|
||||
anode[prop] = node.accessibleNode;
|
||||
is(anode[prop], node.accessibleNode, `anode.${prop} was assigned AccessibleNode`);
|
||||
anode[prop] = null;
|
||||
is(anode[prop], null, `anode.${prop} was assigned null`);
|
||||
}
|
||||
// Check that the WebIDL is as expected.
|
||||
function checkImplementation(ifrDoc) {
|
||||
let anode = ifrDoc.accessibleNode;
|
||||
@ -188,6 +195,12 @@
|
||||
let adopted_node = anotherDoc.adoptNode(node);
|
||||
is(anode, adopted_node.accessibleNode, "adopting node to another document doesn't change node.accessibleNode");
|
||||
|
||||
const relationProps = ["activeDescendant", "details", "errorMessage"];
|
||||
|
||||
for (const relationProp of relationProps) {
|
||||
testRelationProp(anode, node, relationProp);
|
||||
}
|
||||
|
||||
finish();
|
||||
}
|
||||
</script>
|
||||
|
@ -105,7 +105,7 @@ var AccessFuTest = {
|
||||
|
||||
finish: function AccessFuTest_finish() {
|
||||
// Disable the console service logging.
|
||||
Logger.test = false;
|
||||
Logger.useConsoleService = false;
|
||||
Logger.logLevel = Logger.INFO;
|
||||
// Finish through idle callback to let AccessFu._disable complete.
|
||||
SimpleTest.executeSoon(function() {
|
||||
@ -116,13 +116,15 @@ var AccessFuTest = {
|
||||
},
|
||||
|
||||
nextTest: function AccessFuTest_nextTest() {
|
||||
var result = gIterator.next();
|
||||
if (result.done) {
|
||||
this.finish();
|
||||
return;
|
||||
}
|
||||
var testFunc = result.value;
|
||||
testFunc();
|
||||
SimpleTest.executeSoon(() => {
|
||||
var result = gIterator.next();
|
||||
if (result.done) {
|
||||
this.finish();
|
||||
return;
|
||||
}
|
||||
var testFunc = result.value;
|
||||
testFunc();
|
||||
});
|
||||
},
|
||||
|
||||
runTests: function AccessFuTest_runTests(aAdditionalPrefs) {
|
||||
@ -139,15 +141,12 @@ var AccessFuTest = {
|
||||
}
|
||||
})();
|
||||
|
||||
Logger.useConsoleService = true;
|
||||
Logger.logLevel = Logger.DEBUG;
|
||||
|
||||
// Start AccessFu and put it in stand-by.
|
||||
ChromeUtils.import("resource://gre/modules/accessibility/AccessFu.jsm");
|
||||
|
||||
AccessFu.readyCallback = function readyCallback() {
|
||||
// Enable logging to the console service.
|
||||
Logger.test = true;
|
||||
Logger.logLevel = Logger.DEBUG;
|
||||
};
|
||||
|
||||
var prefs = [["accessibility.accessfu.notify_output", 1]];
|
||||
prefs.push.apply(prefs, aAdditionalPrefs);
|
||||
|
||||
@ -216,6 +215,10 @@ class AccessFuContentTestRunner {
|
||||
|
||||
async setupMessageManager(aMessageManager) {
|
||||
function contentScript() {
|
||||
ChromeUtils.import("resource://gre/modules/accessibility/Utils.jsm");
|
||||
Logger.logLevel = "DEBUG";
|
||||
Utils.inTest = true;
|
||||
|
||||
addMessageListener("AccessFuTest:Focus", aMessage => {
|
||||
var elem = content.document.querySelector(aMessage.data.selector);
|
||||
if (elem) {
|
||||
@ -231,23 +234,12 @@ class AccessFuContentTestRunner {
|
||||
aMessageManager.loadFrameScript(
|
||||
"data:,(" + contentScript.toString() + ")();", false);
|
||||
|
||||
let readyPromise = new Promise(resolve =>
|
||||
aMessageManager.addMessageListener("AccessFu:Ready", resolve));
|
||||
|
||||
aMessageManager.loadFrameScript(
|
||||
"chrome://global/content/accessibility/content-script.js", false);
|
||||
|
||||
await readyPromise;
|
||||
|
||||
let startedPromise = new Promise(resolve =>
|
||||
aMessageManager.addMessageListener("AccessFu:ContentStarted", resolve));
|
||||
|
||||
aMessageManager.sendAsyncMessage("AccessFu:Start",
|
||||
{ buildApp: "browser",
|
||||
androidSdkVersion: Utils.AndroidSdkVersion,
|
||||
logLevel: "DEBUG",
|
||||
inTest: true });
|
||||
|
||||
await startedPromise;
|
||||
|
||||
aMessageManager.addMessageListener("AccessFu:Present", this);
|
||||
|
@ -1376,6 +1376,9 @@ var gBrowserInit = {
|
||||
// make sure it has a docshell
|
||||
gBrowser.docShell;
|
||||
|
||||
// Remove the speculative focus from the urlbar to let the url be formatted.
|
||||
gURLBar.removeAttribute("focused");
|
||||
|
||||
try {
|
||||
gBrowser.swapBrowsersAndCloseOther(gBrowser.selectedTab, tabToAdopt);
|
||||
} catch (e) {
|
||||
|
@ -8,7 +8,7 @@
|
||||
* Color the boxes in the treemap
|
||||
*/
|
||||
|
||||
const TYPES = [ "objects", "other", "strings", "scripts" ];
|
||||
const TYPES = [ "objects", "other", "strings", "scripts", "domNode" ];
|
||||
|
||||
// The factors determine how much the hue shifts
|
||||
const TYPE_FACTOR = TYPES.length * 3;
|
||||
|
@ -122,6 +122,7 @@ actions.RESIZE_SHORTEST_PATHS = "resize-shortest-paths";
|
||||
|
||||
const COUNT = Object.freeze({ by: "count", count: true, bytes: true });
|
||||
const INTERNAL_TYPE = Object.freeze({ by: "internalType", then: COUNT });
|
||||
const DESCRIPTIVE_TYPE = Object.freeze({ by: "descriptiveType", then: COUNT });
|
||||
const ALLOCATION_STACK = Object.freeze({
|
||||
by: "allocationStack", then: COUNT,
|
||||
noStack: COUNT
|
||||
@ -137,6 +138,7 @@ const COARSE_TYPE = Object.freeze({
|
||||
noFilename: INTERNAL_TYPE
|
||||
},
|
||||
other: INTERNAL_TYPE,
|
||||
domNode: DESCRIPTIVE_TYPE,
|
||||
});
|
||||
|
||||
exports.censusDisplays = Object.freeze({
|
||||
@ -186,6 +188,7 @@ const DOMINATOR_TREE_LABEL_COARSE_TYPE = Object.freeze({
|
||||
}),
|
||||
strings: INTERNAL_TYPE,
|
||||
other: INTERNAL_TYPE,
|
||||
domNode: DESCRIPTIVE_TYPE,
|
||||
});
|
||||
|
||||
exports.labelDisplays = Object.freeze({
|
||||
|
@ -32,8 +32,8 @@ add_task(async function() {
|
||||
};
|
||||
drawBox(ctx, node, borderWidth, dragZoom, padding);
|
||||
ok(true, JSON.stringify([ctx, fillRectValues, strokeRectValues]));
|
||||
equal(ctx.fillStyle, "hsl(210,60%,70%)", "The fillStyle is set");
|
||||
equal(ctx.strokeStyle, "hsl(210,60%,35%)", "The strokeStyle is set");
|
||||
equal(ctx.fillStyle, "hsl(204,60%,70%)", "The fillStyle is set");
|
||||
equal(ctx.strokeStyle, "hsl(204,60%,35%)", "The strokeStyle is set");
|
||||
equal(ctx.lineWidth, 1, "The lineWidth is set");
|
||||
deepEqual(fillRectValues, [10.5, 20.5, 49, 69], "Draws a filled rectangle");
|
||||
deepEqual(strokeRectValues, [10.5, 20.5, 49, 69], "Draws a stroked rectangle");
|
||||
|
@ -80,6 +80,14 @@ EDGES.internalType = function(breakdown, report) {
|
||||
}));
|
||||
};
|
||||
|
||||
EDGES.descriptiveType = function(breakdown, report) {
|
||||
return Object.keys(report).map(key => ({
|
||||
edge: key,
|
||||
referent: report[key],
|
||||
breakdown: breakdown.then
|
||||
}));
|
||||
};
|
||||
|
||||
EDGES.objectClass = function(breakdown, report) {
|
||||
return Object.keys(report).map(key => ({
|
||||
edge: key,
|
||||
@ -94,6 +102,7 @@ EDGES.coarseType = function(breakdown, report) {
|
||||
{ edge: "scripts", referent: report.scripts, breakdown: breakdown.scripts },
|
||||
{ edge: "strings", referent: report.strings, breakdown: breakdown.strings },
|
||||
{ edge: "other", referent: report.other, breakdown: breakdown.other },
|
||||
{ edge: "domNode", referent: report.domNode, breakdown: breakdown.domNode },
|
||||
];
|
||||
};
|
||||
|
||||
|
@ -48,6 +48,8 @@ public:
|
||||
::google::protobuf::uint64 jsobjectclassnameref_;
|
||||
::google::protobuf::internal::ArenaStringPtr scriptfilename_;
|
||||
::google::protobuf::uint64 scriptfilenameref_;
|
||||
::google::protobuf::internal::ArenaStringPtr descriptivetypename_;
|
||||
::google::protobuf::uint64 descriptivetypenameref_;
|
||||
} _Node_default_instance_;
|
||||
class EdgeDefaultTypeInternal {
|
||||
public:
|
||||
@ -1749,6 +1751,8 @@ const int Node::kJsObjectClassNameRefFieldNumber;
|
||||
const int Node::kCoarseTypeFieldNumber;
|
||||
const int Node::kScriptFilenameFieldNumber;
|
||||
const int Node::kScriptFilenameRefFieldNumber;
|
||||
const int Node::kDescriptiveTypeNameFieldNumber;
|
||||
const int Node::kDescriptiveTypeNameRefFieldNumber;
|
||||
#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
|
||||
|
||||
Node::Node()
|
||||
@ -1816,6 +1820,20 @@ Node::Node(const Node& from)
|
||||
break;
|
||||
}
|
||||
}
|
||||
clear_has_descriptiveTypeNameOrRef();
|
||||
switch (from.descriptiveTypeNameOrRef_case()) {
|
||||
case kDescriptiveTypeName: {
|
||||
set_descriptivetypename(from.descriptivetypename());
|
||||
break;
|
||||
}
|
||||
case kDescriptiveTypeNameRef: {
|
||||
set_descriptivetypenameref(from.descriptivetypenameref());
|
||||
break;
|
||||
}
|
||||
case DESCRIPTIVETYPENAMEORREF_NOT_SET: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// @@protoc_insertion_point(copy_constructor:mozilla.devtools.protobuf.Node)
|
||||
}
|
||||
|
||||
@ -1827,6 +1845,7 @@ void Node::SharedCtor() {
|
||||
clear_has_TypeNameOrRef();
|
||||
clear_has_JSObjectClassNameOrRef();
|
||||
clear_has_ScriptFilenameOrRef();
|
||||
clear_has_descriptiveTypeNameOrRef();
|
||||
}
|
||||
|
||||
Node::~Node() {
|
||||
@ -1845,6 +1864,9 @@ void Node::SharedDtor() {
|
||||
if (has_ScriptFilenameOrRef()) {
|
||||
clear_ScriptFilenameOrRef();
|
||||
}
|
||||
if (has_descriptiveTypeNameOrRef()) {
|
||||
clear_descriptiveTypeNameOrRef();
|
||||
}
|
||||
}
|
||||
|
||||
void Node::SetCachedSize(int size) const {
|
||||
@ -1919,6 +1941,24 @@ void Node::clear_ScriptFilenameOrRef() {
|
||||
_oneof_case_[2] = SCRIPTFILENAMEORREF_NOT_SET;
|
||||
}
|
||||
|
||||
void Node::clear_descriptiveTypeNameOrRef() {
|
||||
// @@protoc_insertion_point(one_of_clear_start:mozilla.devtools.protobuf.Node)
|
||||
switch (descriptiveTypeNameOrRef_case()) {
|
||||
case kDescriptiveTypeName: {
|
||||
descriptiveTypeNameOrRef_.descriptivetypename_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
break;
|
||||
}
|
||||
case kDescriptiveTypeNameRef: {
|
||||
// No need to clear
|
||||
break;
|
||||
}
|
||||
case DESCRIPTIVETYPENAMEORREF_NOT_SET: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
_oneof_case_[3] = DESCRIPTIVETYPENAMEORREF_NOT_SET;
|
||||
}
|
||||
|
||||
|
||||
void Node::Clear() {
|
||||
// @@protoc_insertion_point(message_clear_start:mozilla.devtools.protobuf.Node)
|
||||
@ -1940,6 +1980,7 @@ void Node::Clear() {
|
||||
clear_TypeNameOrRef();
|
||||
clear_JSObjectClassNameOrRef();
|
||||
clear_ScriptFilenameOrRef();
|
||||
clear_descriptiveTypeNameOrRef();
|
||||
_has_bits_.Clear();
|
||||
_internal_metadata_.Clear();
|
||||
}
|
||||
@ -2107,6 +2148,33 @@ bool Node::MergePartialFromCodedStream(
|
||||
break;
|
||||
}
|
||||
|
||||
// optional bytes descriptiveTypeName = 12;
|
||||
case 12: {
|
||||
if (static_cast< ::google::protobuf::uint8>(tag) ==
|
||||
static_cast< ::google::protobuf::uint8>(98u /* 98 & 0xFF */)) {
|
||||
DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
|
||||
input, this->mutable_descriptivetypename()));
|
||||
} else {
|
||||
goto handle_unusual;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// optional uint64 descriptiveTypeNameRef = 13;
|
||||
case 13: {
|
||||
if (static_cast< ::google::protobuf::uint8>(tag) ==
|
||||
static_cast< ::google::protobuf::uint8>(104u /* 104 & 0xFF */)) {
|
||||
clear_descriptiveTypeNameOrRef();
|
||||
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
|
||||
::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
|
||||
input, &descriptiveTypeNameOrRef_.descriptivetypenameref_)));
|
||||
set_has_descriptivetypenameref();
|
||||
} else {
|
||||
goto handle_unusual;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
handle_unusual:
|
||||
if (tag == 0) {
|
||||
@ -2192,6 +2260,16 @@ void Node::SerializeWithCachedSizes(
|
||||
break;
|
||||
default: ;
|
||||
}
|
||||
switch (descriptiveTypeNameOrRef_case()) {
|
||||
case kDescriptiveTypeName:
|
||||
::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(
|
||||
12, this->descriptivetypename(), output);
|
||||
break;
|
||||
case kDescriptiveTypeNameRef:
|
||||
::google::protobuf::internal::WireFormatLite::WriteUInt64(13, this->descriptivetypenameref(), output);
|
||||
break;
|
||||
default: ;
|
||||
}
|
||||
output->WriteRaw(_internal_metadata_.unknown_fields().data(),
|
||||
static_cast<int>(_internal_metadata_.unknown_fields().size()));
|
||||
// @@protoc_insertion_point(serialize_end:mozilla.devtools.protobuf.Node)
|
||||
@ -2301,6 +2379,25 @@ size_t Node::ByteSizeLong() const {
|
||||
break;
|
||||
}
|
||||
}
|
||||
switch (descriptiveTypeNameOrRef_case()) {
|
||||
// optional bytes descriptiveTypeName = 12;
|
||||
case kDescriptiveTypeName: {
|
||||
total_size += 1 +
|
||||
::google::protobuf::internal::WireFormatLite::BytesSize(
|
||||
this->descriptivetypename());
|
||||
break;
|
||||
}
|
||||
// optional uint64 descriptiveTypeNameRef = 13;
|
||||
case kDescriptiveTypeNameRef: {
|
||||
total_size += 1 +
|
||||
::google::protobuf::internal::WireFormatLite::UInt64Size(
|
||||
this->descriptivetypenameref());
|
||||
break;
|
||||
}
|
||||
case DESCRIPTIVETYPENAMEORREF_NOT_SET: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
|
||||
GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
|
||||
_cached_size_ = cached_size;
|
||||
@ -2376,6 +2473,19 @@ void Node::MergeFrom(const Node& from) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
switch (from.descriptiveTypeNameOrRef_case()) {
|
||||
case kDescriptiveTypeName: {
|
||||
set_descriptivetypename(from.descriptivetypename());
|
||||
break;
|
||||
}
|
||||
case kDescriptiveTypeNameRef: {
|
||||
set_descriptivetypenameref(from.descriptivetypenameref());
|
||||
break;
|
||||
}
|
||||
case DESCRIPTIVETYPENAMEORREF_NOT_SET: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Node::CopyFrom(const Node& from) {
|
||||
@ -2406,6 +2516,8 @@ void Node::InternalSwap(Node* other) {
|
||||
swap(_oneof_case_[1], other->_oneof_case_[1]);
|
||||
swap(ScriptFilenameOrRef_, other->ScriptFilenameOrRef_);
|
||||
swap(_oneof_case_[2], other->_oneof_case_[2]);
|
||||
swap(descriptiveTypeNameOrRef_, other->descriptiveTypeNameOrRef_);
|
||||
swap(_oneof_case_[3], other->_oneof_case_[3]);
|
||||
swap(_has_bits_[0], other->_has_bits_[0]);
|
||||
_internal_metadata_.Swap(&other->_internal_metadata_);
|
||||
swap(_cached_size_, other->_cached_size_);
|
||||
@ -2938,6 +3050,130 @@ void Node::set_scriptfilenameref(::google::protobuf::uint64 value) {
|
||||
// @@protoc_insertion_point(field_set:mozilla.devtools.protobuf.Node.scriptFilenameRef)
|
||||
}
|
||||
|
||||
// optional bytes descriptiveTypeName = 12;
|
||||
bool Node::has_descriptivetypename() const {
|
||||
return descriptiveTypeNameOrRef_case() == kDescriptiveTypeName;
|
||||
}
|
||||
void Node::set_has_descriptivetypename() {
|
||||
_oneof_case_[3] = kDescriptiveTypeName;
|
||||
}
|
||||
void Node::clear_descriptivetypename() {
|
||||
if (has_descriptivetypename()) {
|
||||
descriptiveTypeNameOrRef_.descriptivetypename_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
clear_has_descriptiveTypeNameOrRef();
|
||||
}
|
||||
}
|
||||
const ::std::string& Node::descriptivetypename() const {
|
||||
// @@protoc_insertion_point(field_get:mozilla.devtools.protobuf.Node.descriptiveTypeName)
|
||||
if (has_descriptivetypename()) {
|
||||
return descriptiveTypeNameOrRef_.descriptivetypename_.GetNoArena();
|
||||
}
|
||||
return *&::google::protobuf::internal::GetEmptyStringAlreadyInited();
|
||||
}
|
||||
void Node::set_descriptivetypename(const ::std::string& value) {
|
||||
// @@protoc_insertion_point(field_set:mozilla.devtools.protobuf.Node.descriptiveTypeName)
|
||||
if (!has_descriptivetypename()) {
|
||||
clear_descriptiveTypeNameOrRef();
|
||||
set_has_descriptivetypename();
|
||||
descriptiveTypeNameOrRef_.descriptivetypename_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
descriptiveTypeNameOrRef_.descriptivetypename_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
|
||||
// @@protoc_insertion_point(field_set:mozilla.devtools.protobuf.Node.descriptiveTypeName)
|
||||
}
|
||||
#if LANG_CXX11
|
||||
void Node::set_descriptivetypename(::std::string&& value) {
|
||||
// @@protoc_insertion_point(field_set:mozilla.devtools.protobuf.Node.descriptiveTypeName)
|
||||
if (!has_descriptivetypename()) {
|
||||
clear_descriptiveTypeNameOrRef();
|
||||
set_has_descriptivetypename();
|
||||
descriptiveTypeNameOrRef_.descriptivetypename_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
descriptiveTypeNameOrRef_.descriptivetypename_.SetNoArena(
|
||||
&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
|
||||
// @@protoc_insertion_point(field_set_rvalue:mozilla.devtools.protobuf.Node.descriptiveTypeName)
|
||||
}
|
||||
#endif
|
||||
void Node::set_descriptivetypename(const char* value) {
|
||||
GOOGLE_DCHECK(value != NULL);
|
||||
if (!has_descriptivetypename()) {
|
||||
clear_descriptiveTypeNameOrRef();
|
||||
set_has_descriptivetypename();
|
||||
descriptiveTypeNameOrRef_.descriptivetypename_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
descriptiveTypeNameOrRef_.descriptivetypename_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
|
||||
::std::string(value));
|
||||
// @@protoc_insertion_point(field_set_char:mozilla.devtools.protobuf.Node.descriptiveTypeName)
|
||||
}
|
||||
void Node::set_descriptivetypename(const void* value, size_t size) {
|
||||
if (!has_descriptivetypename()) {
|
||||
clear_descriptiveTypeNameOrRef();
|
||||
set_has_descriptivetypename();
|
||||
descriptiveTypeNameOrRef_.descriptivetypename_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
descriptiveTypeNameOrRef_.descriptivetypename_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
|
||||
reinterpret_cast<const char*>(value), size));
|
||||
// @@protoc_insertion_point(field_set_pointer:mozilla.devtools.protobuf.Node.descriptiveTypeName)
|
||||
}
|
||||
::std::string* Node::mutable_descriptivetypename() {
|
||||
if (!has_descriptivetypename()) {
|
||||
clear_descriptiveTypeNameOrRef();
|
||||
set_has_descriptivetypename();
|
||||
descriptiveTypeNameOrRef_.descriptivetypename_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
// @@protoc_insertion_point(field_mutable:mozilla.devtools.protobuf.Node.descriptiveTypeName)
|
||||
return descriptiveTypeNameOrRef_.descriptivetypename_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
::std::string* Node::release_descriptivetypename() {
|
||||
// @@protoc_insertion_point(field_release:mozilla.devtools.protobuf.Node.descriptiveTypeName)
|
||||
if (has_descriptivetypename()) {
|
||||
clear_has_descriptiveTypeNameOrRef();
|
||||
return descriptiveTypeNameOrRef_.descriptivetypename_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
void Node::set_allocated_descriptivetypename(::std::string* descriptivetypename) {
|
||||
if (!has_descriptivetypename()) {
|
||||
descriptiveTypeNameOrRef_.descriptivetypename_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
clear_descriptiveTypeNameOrRef();
|
||||
if (descriptivetypename != NULL) {
|
||||
set_has_descriptivetypename();
|
||||
descriptiveTypeNameOrRef_.descriptivetypename_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
|
||||
descriptivetypename);
|
||||
}
|
||||
// @@protoc_insertion_point(field_set_allocated:mozilla.devtools.protobuf.Node.descriptiveTypeName)
|
||||
}
|
||||
|
||||
// optional uint64 descriptiveTypeNameRef = 13;
|
||||
bool Node::has_descriptivetypenameref() const {
|
||||
return descriptiveTypeNameOrRef_case() == kDescriptiveTypeNameRef;
|
||||
}
|
||||
void Node::set_has_descriptivetypenameref() {
|
||||
_oneof_case_[3] = kDescriptiveTypeNameRef;
|
||||
}
|
||||
void Node::clear_descriptivetypenameref() {
|
||||
if (has_descriptivetypenameref()) {
|
||||
descriptiveTypeNameOrRef_.descriptivetypenameref_ = GOOGLE_ULONGLONG(0);
|
||||
clear_has_descriptiveTypeNameOrRef();
|
||||
}
|
||||
}
|
||||
::google::protobuf::uint64 Node::descriptivetypenameref() const {
|
||||
// @@protoc_insertion_point(field_get:mozilla.devtools.protobuf.Node.descriptiveTypeNameRef)
|
||||
if (has_descriptivetypenameref()) {
|
||||
return descriptiveTypeNameOrRef_.descriptivetypenameref_;
|
||||
}
|
||||
return GOOGLE_ULONGLONG(0);
|
||||
}
|
||||
void Node::set_descriptivetypenameref(::google::protobuf::uint64 value) {
|
||||
if (!has_descriptivetypenameref()) {
|
||||
clear_descriptiveTypeNameOrRef();
|
||||
set_has_descriptivetypenameref();
|
||||
}
|
||||
descriptiveTypeNameOrRef_.descriptivetypenameref_ = value;
|
||||
// @@protoc_insertion_point(field_set:mozilla.devtools.protobuf.Node.descriptiveTypeNameRef)
|
||||
}
|
||||
|
||||
bool Node::has_TypeNameOrRef() const {
|
||||
return TypeNameOrRef_case() != TYPENAMEORREF_NOT_SET;
|
||||
}
|
||||
@ -2956,6 +3192,12 @@ bool Node::has_ScriptFilenameOrRef() const {
|
||||
void Node::clear_has_ScriptFilenameOrRef() {
|
||||
_oneof_case_[2] = SCRIPTFILENAMEORREF_NOT_SET;
|
||||
}
|
||||
bool Node::has_descriptiveTypeNameOrRef() const {
|
||||
return descriptiveTypeNameOrRef_case() != DESCRIPTIVETYPENAMEORREF_NOT_SET;
|
||||
}
|
||||
void Node::clear_has_descriptiveTypeNameOrRef() {
|
||||
_oneof_case_[3] = DESCRIPTIVETYPENAMEORREF_NOT_SET;
|
||||
}
|
||||
Node::TypeNameOrRefCase Node::TypeNameOrRef_case() const {
|
||||
return Node::TypeNameOrRefCase(_oneof_case_[0]);
|
||||
}
|
||||
@ -2965,6 +3207,9 @@ Node::JSObjectClassNameOrRefCase Node::JSObjectClassNameOrRef_case() const {
|
||||
Node::ScriptFilenameOrRefCase Node::ScriptFilenameOrRef_case() const {
|
||||
return Node::ScriptFilenameOrRefCase(_oneof_case_[2]);
|
||||
}
|
||||
Node::DescriptiveTypeNameOrRefCase Node::descriptiveTypeNameOrRef_case() const {
|
||||
return Node::DescriptiveTypeNameOrRefCase(_oneof_case_[3]);
|
||||
}
|
||||
#endif // PROTOBUF_INLINE_NOT_IN_HEADERS
|
||||
|
||||
// ===================================================================
|
||||
|
@ -605,6 +605,12 @@ class Node : public ::google::protobuf::MessageLite /* @@protoc_insertion_point(
|
||||
SCRIPTFILENAMEORREF_NOT_SET = 0,
|
||||
};
|
||||
|
||||
enum DescriptiveTypeNameOrRefCase {
|
||||
kDescriptiveTypeName = 12,
|
||||
kDescriptiveTypeNameRef = 13,
|
||||
DESCRIPTIVETYPENAMEORREF_NOT_SET = 0,
|
||||
};
|
||||
|
||||
static inline const Node* internal_default_instance() {
|
||||
return reinterpret_cast<const Node*>(
|
||||
&_Node_default_instance_);
|
||||
@ -764,9 +770,32 @@ class Node : public ::google::protobuf::MessageLite /* @@protoc_insertion_point(
|
||||
::google::protobuf::uint64 scriptfilenameref() const;
|
||||
void set_scriptfilenameref(::google::protobuf::uint64 value);
|
||||
|
||||
// optional bytes descriptiveTypeName = 12;
|
||||
bool has_descriptivetypename() const;
|
||||
void clear_descriptivetypename();
|
||||
static const int kDescriptiveTypeNameFieldNumber = 12;
|
||||
const ::std::string& descriptivetypename() const;
|
||||
void set_descriptivetypename(const ::std::string& value);
|
||||
#if LANG_CXX11
|
||||
void set_descriptivetypename(::std::string&& value);
|
||||
#endif
|
||||
void set_descriptivetypename(const char* value);
|
||||
void set_descriptivetypename(const void* value, size_t size);
|
||||
::std::string* mutable_descriptivetypename();
|
||||
::std::string* release_descriptivetypename();
|
||||
void set_allocated_descriptivetypename(::std::string* descriptivetypename);
|
||||
|
||||
// optional uint64 descriptiveTypeNameRef = 13;
|
||||
bool has_descriptivetypenameref() const;
|
||||
void clear_descriptivetypenameref();
|
||||
static const int kDescriptiveTypeNameRefFieldNumber = 13;
|
||||
::google::protobuf::uint64 descriptivetypenameref() const;
|
||||
void set_descriptivetypenameref(::google::protobuf::uint64 value);
|
||||
|
||||
TypeNameOrRefCase TypeNameOrRef_case() const;
|
||||
JSObjectClassNameOrRefCase JSObjectClassNameOrRef_case() const;
|
||||
ScriptFilenameOrRefCase ScriptFilenameOrRef_case() const;
|
||||
DescriptiveTypeNameOrRefCase descriptiveTypeNameOrRef_case() const;
|
||||
// @@protoc_insertion_point(class_scope:mozilla.devtools.protobuf.Node)
|
||||
private:
|
||||
void set_has_id();
|
||||
@ -783,6 +812,8 @@ class Node : public ::google::protobuf::MessageLite /* @@protoc_insertion_point(
|
||||
void clear_has_coarsetype();
|
||||
void set_has_scriptfilename();
|
||||
void set_has_scriptfilenameref();
|
||||
void set_has_descriptivetypename();
|
||||
void set_has_descriptivetypenameref();
|
||||
|
||||
inline bool has_TypeNameOrRef() const;
|
||||
void clear_TypeNameOrRef();
|
||||
@ -796,6 +827,10 @@ class Node : public ::google::protobuf::MessageLite /* @@protoc_insertion_point(
|
||||
void clear_ScriptFilenameOrRef();
|
||||
inline void clear_has_ScriptFilenameOrRef();
|
||||
|
||||
inline bool has_descriptiveTypeNameOrRef() const;
|
||||
void clear_descriptiveTypeNameOrRef();
|
||||
inline void clear_has_descriptiveTypeNameOrRef();
|
||||
|
||||
::google::protobuf::internal::InternalMetadataWithArenaLite _internal_metadata_;
|
||||
::google::protobuf::internal::HasBits<1> _has_bits_;
|
||||
mutable int _cached_size_;
|
||||
@ -819,7 +854,12 @@ class Node : public ::google::protobuf::MessageLite /* @@protoc_insertion_point(
|
||||
::google::protobuf::internal::ArenaStringPtr scriptfilename_;
|
||||
::google::protobuf::uint64 scriptfilenameref_;
|
||||
} ScriptFilenameOrRef_;
|
||||
::google::protobuf::uint32 _oneof_case_[3];
|
||||
union DescriptiveTypeNameOrRefUnion {
|
||||
DescriptiveTypeNameOrRefUnion() {}
|
||||
::google::protobuf::internal::ArenaStringPtr descriptivetypename_;
|
||||
::google::protobuf::uint64 descriptivetypenameref_;
|
||||
} descriptiveTypeNameOrRef_;
|
||||
::google::protobuf::uint32 _oneof_case_[4];
|
||||
|
||||
friend struct protobuf_CoreDump_2eproto::TableStruct;
|
||||
};
|
||||
@ -2057,6 +2097,130 @@ inline void Node::set_scriptfilenameref(::google::protobuf::uint64 value) {
|
||||
// @@protoc_insertion_point(field_set:mozilla.devtools.protobuf.Node.scriptFilenameRef)
|
||||
}
|
||||
|
||||
// optional bytes descriptiveTypeName = 12;
|
||||
inline bool Node::has_descriptivetypename() const {
|
||||
return descriptiveTypeNameOrRef_case() == kDescriptiveTypeName;
|
||||
}
|
||||
inline void Node::set_has_descriptivetypename() {
|
||||
_oneof_case_[3] = kDescriptiveTypeName;
|
||||
}
|
||||
inline void Node::clear_descriptivetypename() {
|
||||
if (has_descriptivetypename()) {
|
||||
descriptiveTypeNameOrRef_.descriptivetypename_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
clear_has_descriptiveTypeNameOrRef();
|
||||
}
|
||||
}
|
||||
inline const ::std::string& Node::descriptivetypename() const {
|
||||
// @@protoc_insertion_point(field_get:mozilla.devtools.protobuf.Node.descriptiveTypeName)
|
||||
if (has_descriptivetypename()) {
|
||||
return descriptiveTypeNameOrRef_.descriptivetypename_.GetNoArena();
|
||||
}
|
||||
return *&::google::protobuf::internal::GetEmptyStringAlreadyInited();
|
||||
}
|
||||
inline void Node::set_descriptivetypename(const ::std::string& value) {
|
||||
// @@protoc_insertion_point(field_set:mozilla.devtools.protobuf.Node.descriptiveTypeName)
|
||||
if (!has_descriptivetypename()) {
|
||||
clear_descriptiveTypeNameOrRef();
|
||||
set_has_descriptivetypename();
|
||||
descriptiveTypeNameOrRef_.descriptivetypename_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
descriptiveTypeNameOrRef_.descriptivetypename_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
|
||||
// @@protoc_insertion_point(field_set:mozilla.devtools.protobuf.Node.descriptiveTypeName)
|
||||
}
|
||||
#if LANG_CXX11
|
||||
inline void Node::set_descriptivetypename(::std::string&& value) {
|
||||
// @@protoc_insertion_point(field_set:mozilla.devtools.protobuf.Node.descriptiveTypeName)
|
||||
if (!has_descriptivetypename()) {
|
||||
clear_descriptiveTypeNameOrRef();
|
||||
set_has_descriptivetypename();
|
||||
descriptiveTypeNameOrRef_.descriptivetypename_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
descriptiveTypeNameOrRef_.descriptivetypename_.SetNoArena(
|
||||
&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
|
||||
// @@protoc_insertion_point(field_set_rvalue:mozilla.devtools.protobuf.Node.descriptiveTypeName)
|
||||
}
|
||||
#endif
|
||||
inline void Node::set_descriptivetypename(const char* value) {
|
||||
GOOGLE_DCHECK(value != NULL);
|
||||
if (!has_descriptivetypename()) {
|
||||
clear_descriptiveTypeNameOrRef();
|
||||
set_has_descriptivetypename();
|
||||
descriptiveTypeNameOrRef_.descriptivetypename_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
descriptiveTypeNameOrRef_.descriptivetypename_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
|
||||
::std::string(value));
|
||||
// @@protoc_insertion_point(field_set_char:mozilla.devtools.protobuf.Node.descriptiveTypeName)
|
||||
}
|
||||
inline void Node::set_descriptivetypename(const void* value, size_t size) {
|
||||
if (!has_descriptivetypename()) {
|
||||
clear_descriptiveTypeNameOrRef();
|
||||
set_has_descriptivetypename();
|
||||
descriptiveTypeNameOrRef_.descriptivetypename_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
descriptiveTypeNameOrRef_.descriptivetypename_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
|
||||
reinterpret_cast<const char*>(value), size));
|
||||
// @@protoc_insertion_point(field_set_pointer:mozilla.devtools.protobuf.Node.descriptiveTypeName)
|
||||
}
|
||||
inline ::std::string* Node::mutable_descriptivetypename() {
|
||||
if (!has_descriptivetypename()) {
|
||||
clear_descriptiveTypeNameOrRef();
|
||||
set_has_descriptivetypename();
|
||||
descriptiveTypeNameOrRef_.descriptivetypename_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
// @@protoc_insertion_point(field_mutable:mozilla.devtools.protobuf.Node.descriptiveTypeName)
|
||||
return descriptiveTypeNameOrRef_.descriptivetypename_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
inline ::std::string* Node::release_descriptivetypename() {
|
||||
// @@protoc_insertion_point(field_release:mozilla.devtools.protobuf.Node.descriptiveTypeName)
|
||||
if (has_descriptivetypename()) {
|
||||
clear_has_descriptiveTypeNameOrRef();
|
||||
return descriptiveTypeNameOrRef_.descriptivetypename_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
inline void Node::set_allocated_descriptivetypename(::std::string* descriptivetypename) {
|
||||
if (!has_descriptivetypename()) {
|
||||
descriptiveTypeNameOrRef_.descriptivetypename_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
clear_descriptiveTypeNameOrRef();
|
||||
if (descriptivetypename != NULL) {
|
||||
set_has_descriptivetypename();
|
||||
descriptiveTypeNameOrRef_.descriptivetypename_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
|
||||
descriptivetypename);
|
||||
}
|
||||
// @@protoc_insertion_point(field_set_allocated:mozilla.devtools.protobuf.Node.descriptiveTypeName)
|
||||
}
|
||||
|
||||
// optional uint64 descriptiveTypeNameRef = 13;
|
||||
inline bool Node::has_descriptivetypenameref() const {
|
||||
return descriptiveTypeNameOrRef_case() == kDescriptiveTypeNameRef;
|
||||
}
|
||||
inline void Node::set_has_descriptivetypenameref() {
|
||||
_oneof_case_[3] = kDescriptiveTypeNameRef;
|
||||
}
|
||||
inline void Node::clear_descriptivetypenameref() {
|
||||
if (has_descriptivetypenameref()) {
|
||||
descriptiveTypeNameOrRef_.descriptivetypenameref_ = GOOGLE_ULONGLONG(0);
|
||||
clear_has_descriptiveTypeNameOrRef();
|
||||
}
|
||||
}
|
||||
inline ::google::protobuf::uint64 Node::descriptivetypenameref() const {
|
||||
// @@protoc_insertion_point(field_get:mozilla.devtools.protobuf.Node.descriptiveTypeNameRef)
|
||||
if (has_descriptivetypenameref()) {
|
||||
return descriptiveTypeNameOrRef_.descriptivetypenameref_;
|
||||
}
|
||||
return GOOGLE_ULONGLONG(0);
|
||||
}
|
||||
inline void Node::set_descriptivetypenameref(::google::protobuf::uint64 value) {
|
||||
if (!has_descriptivetypenameref()) {
|
||||
clear_descriptiveTypeNameOrRef();
|
||||
set_has_descriptivetypenameref();
|
||||
}
|
||||
descriptiveTypeNameOrRef_.descriptivetypenameref_ = value;
|
||||
// @@protoc_insertion_point(field_set:mozilla.devtools.protobuf.Node.descriptiveTypeNameRef)
|
||||
}
|
||||
|
||||
inline bool Node::has_TypeNameOrRef() const {
|
||||
return TypeNameOrRef_case() != TYPENAMEORREF_NOT_SET;
|
||||
}
|
||||
@ -2075,6 +2239,12 @@ inline bool Node::has_ScriptFilenameOrRef() const {
|
||||
inline void Node::clear_has_ScriptFilenameOrRef() {
|
||||
_oneof_case_[2] = SCRIPTFILENAMEORREF_NOT_SET;
|
||||
}
|
||||
inline bool Node::has_descriptiveTypeNameOrRef() const {
|
||||
return descriptiveTypeNameOrRef_case() != DESCRIPTIVETYPENAMEORREF_NOT_SET;
|
||||
}
|
||||
inline void Node::clear_has_descriptiveTypeNameOrRef() {
|
||||
_oneof_case_[3] = DESCRIPTIVETYPENAMEORREF_NOT_SET;
|
||||
}
|
||||
inline Node::TypeNameOrRefCase Node::TypeNameOrRef_case() const {
|
||||
return Node::TypeNameOrRefCase(_oneof_case_[0]);
|
||||
}
|
||||
@ -2084,6 +2254,9 @@ inline Node::JSObjectClassNameOrRefCase Node::JSObjectClassNameOrRef_case() cons
|
||||
inline Node::ScriptFilenameOrRefCase Node::ScriptFilenameOrRef_case() const {
|
||||
return Node::ScriptFilenameOrRefCase(_oneof_case_[2]);
|
||||
}
|
||||
inline Node::DescriptiveTypeNameOrRefCase Node::descriptiveTypeNameOrRef_case() const {
|
||||
return Node::DescriptiveTypeNameOrRefCase(_oneof_case_[3]);
|
||||
}
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
// Edge
|
||||
|
@ -106,31 +106,37 @@ message StackFrame {
|
||||
|
||||
// A serialized version of `JS::ubi::Node` and its outgoing edges.
|
||||
message Node {
|
||||
optional uint64 id = 1;
|
||||
optional uint64 id = 1;
|
||||
|
||||
// De-duplicated two-byte string.
|
||||
oneof TypeNameOrRef {
|
||||
bytes typeName = 2;
|
||||
uint64 typeNameRef = 3;
|
||||
bytes typeName = 2;
|
||||
uint64 typeNameRef = 3;
|
||||
}
|
||||
|
||||
optional uint64 size = 4;
|
||||
repeated Edge edges = 5;
|
||||
optional StackFrame allocationStack = 6;
|
||||
optional uint64 size = 4;
|
||||
repeated Edge edges = 5;
|
||||
optional StackFrame allocationStack = 6;
|
||||
|
||||
// De-duplicated one-byte string.
|
||||
oneof JSObjectClassNameOrRef {
|
||||
bytes jsObjectClassName = 7;
|
||||
uint64 jsObjectClassNameRef = 8;
|
||||
bytes jsObjectClassName = 7;
|
||||
uint64 jsObjectClassNameRef = 8;
|
||||
}
|
||||
|
||||
// JS::ubi::CoarseType. Defaults to Other.
|
||||
optional uint32 coarseType = 9 [default = 0];
|
||||
optional uint32 coarseType = 9 [default = 0];
|
||||
|
||||
// De-duplicated one-byte string.
|
||||
oneof ScriptFilenameOrRef {
|
||||
bytes scriptFilename = 10;
|
||||
uint64 scriptFilenameRef = 11;
|
||||
bytes scriptFilename = 10;
|
||||
uint64 scriptFilenameRef = 11;
|
||||
}
|
||||
|
||||
// De-duplicated one-byte string.
|
||||
oneof descriptiveTypeNameOrRef {
|
||||
bytes descriptiveTypeName = 12;
|
||||
uint64 descriptiveTypeNameRef = 13;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -70,6 +70,8 @@ struct DeserializedNode {
|
||||
const char* jsObjectClassName;
|
||||
// A borrowed reference to a string owned by this node's owning HeapSnapshot.
|
||||
const char* scriptFilename;
|
||||
// A borrowed reference to a string owned by this node's owning HeapSnapshot.
|
||||
const char16_t* descriptiveTypeName;
|
||||
// A weak pointer to this node's owning `HeapSnapshot`. Safe without
|
||||
// AddRef'ing because this node's lifetime is equal to that of its owner.
|
||||
HeapSnapshot* owner;
|
||||
@ -82,6 +84,7 @@ struct DeserializedNode {
|
||||
const Maybe<StackFrameId>& allocationStack,
|
||||
const char* className,
|
||||
const char* filename,
|
||||
const char16_t* descriptiveName,
|
||||
HeapSnapshot& owner)
|
||||
: id(id)
|
||||
, coarseType(coarseType)
|
||||
@ -91,6 +94,7 @@ struct DeserializedNode {
|
||||
, allocationStack(allocationStack)
|
||||
, jsObjectClassName(className)
|
||||
, scriptFilename(filename)
|
||||
, descriptiveTypeName(descriptiveName)
|
||||
, owner(&owner)
|
||||
{ }
|
||||
virtual ~DeserializedNode() { }
|
||||
@ -104,6 +108,7 @@ struct DeserializedNode {
|
||||
, allocationStack(rhs.allocationStack)
|
||||
, jsObjectClassName(rhs.jsObjectClassName)
|
||||
, scriptFilename(rhs.scriptFilename)
|
||||
, descriptiveTypeName(rhs.descriptiveTypeName)
|
||||
, owner(rhs.owner)
|
||||
{ }
|
||||
|
||||
@ -132,6 +137,7 @@ protected:
|
||||
, allocationStack(Nothing())
|
||||
, jsObjectClassName(nullptr)
|
||||
, scriptFilename(nullptr)
|
||||
, descriptiveTypeName(nullptr)
|
||||
, owner(nullptr)
|
||||
{ }
|
||||
|
||||
@ -259,6 +265,7 @@ public:
|
||||
Node::Size size(mozilla::MallocSizeOf mallocSizeof) const override;
|
||||
const char* jsObjectClassName() const override { return get().jsObjectClassName; }
|
||||
const char* scriptFilename() const final { return get().scriptFilename; }
|
||||
const char16_t* descriptiveTypeName() const override { return get().descriptiveTypeName; }
|
||||
|
||||
bool hasAllocationStack() const override { return get().allocationStack.isSome(); }
|
||||
StackFrame allocationStack() const override;
|
||||
|
@ -284,11 +284,21 @@ HeapSnapshot::saveNode(const protobuf::Node& node, NodeIdSet& edgeReferents)
|
||||
return false;
|
||||
}
|
||||
|
||||
const char16_t* descriptiveTypeName = nullptr;
|
||||
if (node.descriptiveTypeNameOrRef_case() != protobuf::Node::DESCRIPTIVETYPENAMEORREF_NOT_SET) {
|
||||
Maybe<StringOrRef> descriptiveTypeNameOrRef = GET_STRING_OR_REF(node, descriptivetypename);
|
||||
descriptiveTypeName = getOrInternString<char16_t>(internedTwoByteStrings, descriptiveTypeNameOrRef);
|
||||
if (NS_WARN_IF(!descriptiveTypeName))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(!nodes.putNew(id, DeserializedNode(id, coarseType, typeName,
|
||||
size, std::move(edges),
|
||||
allocationStack,
|
||||
jsObjectClassName,
|
||||
scriptFilename, *this))))
|
||||
scriptFilename,
|
||||
descriptiveTypeName,
|
||||
*this))))
|
||||
{
|
||||
return false;
|
||||
};
|
||||
@ -1340,6 +1350,16 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
if (ubiNode.descriptiveTypeName()) {
|
||||
auto descriptiveTypeName = TwoByteString(ubiNode.descriptiveTypeName());
|
||||
if (NS_WARN_IF(!attachTwoByteString(descriptiveTypeName,
|
||||
[&] (std::string* name) { protobufNode.set_allocated_descriptivetypename(name); },
|
||||
[&] (uint64_t ref) { protobufNode.set_descriptivetypenameref(ref); })))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return writeMessage(protobufNode);
|
||||
}
|
||||
};
|
||||
|
@ -23,6 +23,10 @@ const breakdown = {
|
||||
by: "internalType",
|
||||
then: { by: "count", count: true, bytes: true },
|
||||
},
|
||||
domNode: {
|
||||
by: "descriptiveType",
|
||||
then: { by: "count", count: true, bytes: true },
|
||||
},
|
||||
};
|
||||
|
||||
const description = {
|
||||
@ -32,7 +36,8 @@ const description = {
|
||||
},
|
||||
strings: {},
|
||||
scripts: {},
|
||||
other: {}
|
||||
other: {},
|
||||
domNode: {}
|
||||
};
|
||||
|
||||
const expected = [
|
||||
|
@ -23,6 +23,10 @@ const breakdown = {
|
||||
by: "internalType",
|
||||
then: { by: "count", count: true, bytes: true },
|
||||
},
|
||||
domNode: {
|
||||
by: "descriptiveType",
|
||||
then: { by: "count", count: true, bytes: true },
|
||||
},
|
||||
};
|
||||
|
||||
const description = {
|
||||
@ -31,7 +35,8 @@ const description = {
|
||||
},
|
||||
strings: {},
|
||||
scripts: {},
|
||||
other: {}
|
||||
other: {},
|
||||
domNode: {}
|
||||
};
|
||||
|
||||
const expected = [
|
||||
|
@ -23,6 +23,10 @@ const breakdown = {
|
||||
by: "internalType",
|
||||
then: { by: "count", count: true, bytes: true },
|
||||
},
|
||||
domNode: {
|
||||
by: "descriptiveType",
|
||||
then: { by: "count", count: true, bytes: true },
|
||||
},
|
||||
};
|
||||
|
||||
const description = {
|
||||
@ -33,7 +37,8 @@ const description = {
|
||||
"JSString": { count: 1, bytes: 42 },
|
||||
},
|
||||
scripts: {},
|
||||
other: {}
|
||||
other: {},
|
||||
domNode: {}
|
||||
};
|
||||
|
||||
const expected = [
|
||||
|
@ -27,6 +27,10 @@ const breakdown = {
|
||||
by: "internalType",
|
||||
then: { by: "count", count: true, bytes: true },
|
||||
},
|
||||
domNode: {
|
||||
by: "descriptiveType",
|
||||
then: { by: "count", count: true, bytes: true },
|
||||
},
|
||||
};
|
||||
|
||||
const stack = saveStack();
|
||||
@ -38,7 +42,8 @@ const description = {
|
||||
},
|
||||
strings: {},
|
||||
scripts: {},
|
||||
other: {}
|
||||
other: {},
|
||||
domNode: {}
|
||||
};
|
||||
|
||||
const expected = [
|
||||
|
@ -38,7 +38,8 @@ const mockSnapshot = {
|
||||
objects: { count: 0, bytes: 0 },
|
||||
strings: { count: 0, bytes: 0 },
|
||||
scripts: { count: 0, bytes: 0 },
|
||||
other: { SomeType: { count: 1, bytes: 10 } }
|
||||
other: { SomeType: { count: 1, bytes: 10 } },
|
||||
domNode: { count: 0, bytes: 0 },
|
||||
})
|
||||
};
|
||||
|
||||
@ -51,6 +52,7 @@ const breakdown = {
|
||||
by: "internalType",
|
||||
then: { by: "count", count: true, bytes: true }
|
||||
},
|
||||
domNode: { by: "count", count: true, bytes: true },
|
||||
};
|
||||
|
||||
const expected = {
|
||||
|
@ -10,6 +10,7 @@ const breakdown = {
|
||||
scripts: { by: "count", count: true, bytes: true },
|
||||
strings: { by: "count", count: true, bytes: true },
|
||||
other: { by: "count", count: true, bytes: true },
|
||||
domNode: { by: "count", count: true, bytes: true },
|
||||
};
|
||||
|
||||
async function createSnapshotAndDominatorTree(client) {
|
||||
|
@ -12,6 +12,7 @@ const CENSUS_BREAKDOWN = {
|
||||
strings: COUNT,
|
||||
scripts: COUNT,
|
||||
other: COUNT,
|
||||
domNode: COUNT,
|
||||
};
|
||||
|
||||
const LABEL_BREAKDOWN = {
|
||||
|
@ -10,6 +10,7 @@ const breakdown = {
|
||||
scripts: { by: "count", count: true, bytes: true },
|
||||
strings: { by: "count", count: true, bytes: true },
|
||||
other: { by: "count", count: true, bytes: true },
|
||||
domNode: { by: "count", count: true, bytes: true },
|
||||
};
|
||||
|
||||
add_task(async function() {
|
||||
|
@ -10,6 +10,7 @@ const breakdown = {
|
||||
scripts: { by: "count", count: true, bytes: true },
|
||||
strings: { by: "count", count: true, bytes: true },
|
||||
other: { by: "count", count: true, bytes: true },
|
||||
domNode: { by: "count", count: true, bytes: true },
|
||||
};
|
||||
|
||||
add_task(async function() {
|
||||
|
@ -24,6 +24,10 @@ const BREAKDOWN = {
|
||||
by: "internalType",
|
||||
then: { by: "count", count: true, bytes: true },
|
||||
},
|
||||
domNode: {
|
||||
by: "descriptiveType",
|
||||
then: { by: "count", count: true, bytes: true },
|
||||
},
|
||||
};
|
||||
|
||||
add_task(async function() {
|
||||
|
@ -24,6 +24,10 @@ const BREAKDOWN = {
|
||||
by: "internalType",
|
||||
then: { by: "count", count: true, bytes: true },
|
||||
},
|
||||
domNode: {
|
||||
by: "descriptiveType",
|
||||
then: { by: "count", count: true, bytes: true },
|
||||
},
|
||||
};
|
||||
|
||||
add_task(async function() {
|
||||
|
@ -14,6 +14,7 @@ const BREAKDOWN = {
|
||||
strings: countBreakdown,
|
||||
scripts: countBreakdown,
|
||||
other: { by: "internalType", then: countBreakdown },
|
||||
domNode: countBreakdown,
|
||||
};
|
||||
|
||||
const REPORT = {
|
||||
@ -27,6 +28,7 @@ const REPORT = {
|
||||
"js::Shape": { bytes: 30, count: 3 },
|
||||
"js::Shape2": { bytes: 40, count: 4 }
|
||||
},
|
||||
"domNode": { bytes: 0, count: 0 }
|
||||
};
|
||||
|
||||
const EXPECTED = {
|
||||
|
@ -26,6 +26,10 @@ function run_test() {
|
||||
by: "internalType",
|
||||
then: { by: "count", count: true, bytes: true },
|
||||
},
|
||||
domNode: {
|
||||
by: "descriptiveType",
|
||||
then: { by: "count", count: true, bytes: true },
|
||||
}
|
||||
};
|
||||
|
||||
const REPORT = {
|
||||
@ -41,7 +45,8 @@ function run_test() {
|
||||
},
|
||||
other: {
|
||||
"js::Shape": { bytes: 80, count: 8 },
|
||||
}
|
||||
},
|
||||
domNode: { }
|
||||
};
|
||||
|
||||
const EXPECTED = {
|
||||
@ -72,18 +77,18 @@ function run_test() {
|
||||
count: 0,
|
||||
totalCount: 22,
|
||||
children: undefined,
|
||||
id: 14,
|
||||
parent: 13,
|
||||
id: 15,
|
||||
parent: 14,
|
||||
reportLeafIndex: undefined,
|
||||
}
|
||||
],
|
||||
id: 13,
|
||||
parent: 12,
|
||||
id: 14,
|
||||
parent: 13,
|
||||
reportLeafIndex: undefined,
|
||||
}
|
||||
],
|
||||
id: 12,
|
||||
parent: 11,
|
||||
id: 13,
|
||||
parent: 12,
|
||||
reportLeafIndex: 9,
|
||||
},
|
||||
{
|
||||
@ -107,18 +112,18 @@ function run_test() {
|
||||
count: 0,
|
||||
totalCount: 22,
|
||||
children: undefined,
|
||||
id: 17,
|
||||
parent: 16,
|
||||
id: 18,
|
||||
parent: 17,
|
||||
reportLeafIndex: undefined,
|
||||
}
|
||||
],
|
||||
id: 16,
|
||||
parent: 15,
|
||||
id: 17,
|
||||
parent: 16,
|
||||
reportLeafIndex: undefined,
|
||||
}
|
||||
],
|
||||
id: 15,
|
||||
parent: 11,
|
||||
id: 16,
|
||||
parent: 12,
|
||||
reportLeafIndex: 7,
|
||||
},
|
||||
{
|
||||
@ -142,18 +147,18 @@ function run_test() {
|
||||
count: 0,
|
||||
totalCount: 22,
|
||||
children: undefined,
|
||||
id: 20,
|
||||
parent: 19,
|
||||
id: 21,
|
||||
parent: 20,
|
||||
reportLeafIndex: undefined,
|
||||
}
|
||||
],
|
||||
id: 19,
|
||||
parent: 18,
|
||||
id: 20,
|
||||
parent: 19,
|
||||
reportLeafIndex: undefined,
|
||||
}
|
||||
],
|
||||
id: 18,
|
||||
parent: 11,
|
||||
id: 19,
|
||||
parent: 12,
|
||||
reportLeafIndex: 2,
|
||||
},
|
||||
{
|
||||
@ -177,22 +182,22 @@ function run_test() {
|
||||
count: 0,
|
||||
totalCount: 22,
|
||||
children: undefined,
|
||||
id: 23,
|
||||
parent: 22,
|
||||
id: 24,
|
||||
parent: 23,
|
||||
reportLeafIndex: undefined,
|
||||
}
|
||||
],
|
||||
id: 22,
|
||||
parent: 21,
|
||||
id: 23,
|
||||
parent: 22,
|
||||
reportLeafIndex: undefined,
|
||||
}
|
||||
],
|
||||
id: 21,
|
||||
parent: 11,
|
||||
id: 22,
|
||||
parent: 12,
|
||||
reportLeafIndex: 5,
|
||||
},
|
||||
],
|
||||
id: 11,
|
||||
id: 12,
|
||||
parent: undefined,
|
||||
reportLeafIndex: undefined,
|
||||
};
|
||||
|
@ -20,6 +20,7 @@ function run_test() {
|
||||
},
|
||||
strings: { by: "count", count: true, bytes: true },
|
||||
scripts: { by: "count", count: true, bytes: true },
|
||||
domNode: { by: "count", count: true, bytes: true },
|
||||
};
|
||||
|
||||
const REPORT = {
|
||||
@ -31,6 +32,7 @@ function run_test() {
|
||||
},
|
||||
strings: { count: 0, bytes: 0 },
|
||||
scripts: { count: 0, bytes: 0 },
|
||||
domNode: {count: 0, bytes: 0 },
|
||||
};
|
||||
|
||||
const node = censusReportToCensusTreeNode(BREAKDOWN, REPORT, { invert: true });
|
||||
|
@ -10,6 +10,7 @@ const BREAKDOWN = {
|
||||
scripts: { by: "count", count: true, bytes: true },
|
||||
strings: { by: "count", count: true, bytes: true },
|
||||
other: { by: "count", count: true, bytes: true },
|
||||
domNode: { by: "count", count: true, bytes: true },
|
||||
};
|
||||
|
||||
const REPORT1 = {
|
||||
@ -29,6 +30,10 @@ const REPORT1 = {
|
||||
count: 3,
|
||||
bytes: 30,
|
||||
},
|
||||
domNode: {
|
||||
count: 0,
|
||||
bytes: 0,
|
||||
},
|
||||
};
|
||||
|
||||
const REPORT2 = {
|
||||
@ -48,6 +53,10 @@ const REPORT2 = {
|
||||
count: 4,
|
||||
bytes: 40,
|
||||
},
|
||||
domNode: {
|
||||
count: 0,
|
||||
bytes: 0,
|
||||
},
|
||||
};
|
||||
|
||||
const EXPECTED = {
|
||||
@ -67,6 +76,10 @@ const EXPECTED = {
|
||||
count: 1,
|
||||
bytes: 10,
|
||||
},
|
||||
domNode: {
|
||||
count: 0,
|
||||
bytes: 0,
|
||||
},
|
||||
};
|
||||
|
||||
function run_test() {
|
||||
|
@ -31,6 +31,10 @@ const BREAKDOWN = {
|
||||
by: "internalType",
|
||||
then: { by: "count", count: false, bytes: true }
|
||||
},
|
||||
domNode: {
|
||||
by: "internalType",
|
||||
then: { by: "count", count: false, bytes: true }
|
||||
},
|
||||
};
|
||||
|
||||
const stack1 = saveStack();
|
||||
@ -59,7 +63,8 @@ const REPORT1 = {
|
||||
},
|
||||
other: {
|
||||
"mozilla::dom::Thing": { bytes: 1 },
|
||||
}
|
||||
},
|
||||
domNode: {}
|
||||
};
|
||||
|
||||
const REPORT2 = {
|
||||
@ -85,7 +90,8 @@ const REPORT2 = {
|
||||
},
|
||||
other: {
|
||||
"mozilla::dom::OtherThing": { bytes: 1 },
|
||||
}
|
||||
},
|
||||
domNode: {}
|
||||
};
|
||||
|
||||
const EXPECTED = {
|
||||
@ -130,7 +136,8 @@ const EXPECTED = {
|
||||
"mozilla::dom::OtherThing": {
|
||||
"bytes": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"domNode": {},
|
||||
};
|
||||
|
||||
function run_test() {
|
||||
|
@ -24,6 +24,10 @@ function run_test() {
|
||||
by: "internalType",
|
||||
then: { by: "count", count: true, bytes: true },
|
||||
},
|
||||
domNode: {
|
||||
by: "descriptiveType",
|
||||
then: { by: "count", count: true, bytes: true },
|
||||
},
|
||||
};
|
||||
|
||||
const REPORT = {
|
||||
@ -41,7 +45,8 @@ function run_test() {
|
||||
},
|
||||
other: {
|
||||
"js::Shape": { bytes: 80, count: 8 },
|
||||
}
|
||||
},
|
||||
domNode: {}
|
||||
};
|
||||
|
||||
const EXPECTED = {
|
||||
@ -65,8 +70,8 @@ function run_test() {
|
||||
count: 32,
|
||||
totalCount: 32,
|
||||
children: undefined,
|
||||
id: 15,
|
||||
parent: 14,
|
||||
id: 16,
|
||||
parent: 15,
|
||||
reportLeafIndex: 4,
|
||||
},
|
||||
{
|
||||
@ -76,8 +81,8 @@ function run_test() {
|
||||
count: 8,
|
||||
totalCount: 8,
|
||||
children: undefined,
|
||||
id: 16,
|
||||
parent: 14,
|
||||
id: 17,
|
||||
parent: 15,
|
||||
reportLeafIndex: 3,
|
||||
},
|
||||
{
|
||||
@ -87,17 +92,17 @@ function run_test() {
|
||||
count: 5,
|
||||
totalCount: 5,
|
||||
children: undefined,
|
||||
id: 17,
|
||||
parent: 14,
|
||||
id: 18,
|
||||
parent: 15,
|
||||
reportLeafIndex: 2,
|
||||
}
|
||||
],
|
||||
id: 14,
|
||||
parent: 13,
|
||||
id: 15,
|
||||
parent: 14,
|
||||
reportLeafIndex: undefined,
|
||||
}
|
||||
],
|
||||
id: 13,
|
||||
id: 14,
|
||||
parent: undefined,
|
||||
reportLeafIndex: undefined,
|
||||
};
|
||||
|
@ -24,6 +24,10 @@ function run_test() {
|
||||
by: "internalType",
|
||||
then: { by: "count", count: true, bytes: true },
|
||||
},
|
||||
domNode: {
|
||||
by: "descriptiveType",
|
||||
then: { by: "count", count: true, bytes: true },
|
||||
},
|
||||
};
|
||||
|
||||
const REPORT = {
|
||||
@ -41,7 +45,8 @@ function run_test() {
|
||||
},
|
||||
other: {
|
||||
"js::Shape": { bytes: 80, count: 8 },
|
||||
}
|
||||
},
|
||||
domNode: {}
|
||||
};
|
||||
|
||||
const EXPECTED = {
|
||||
@ -51,7 +56,7 @@ function run_test() {
|
||||
count: 0,
|
||||
totalCount: 62,
|
||||
children: undefined,
|
||||
id: 13,
|
||||
id: 14,
|
||||
parent: undefined,
|
||||
reportLeafIndex: undefined,
|
||||
};
|
||||
|
@ -19,6 +19,7 @@ function run_test() {
|
||||
noFilename: INTERNAL_TYPE
|
||||
},
|
||||
other: INTERNAL_TYPE,
|
||||
domNode: { by: "descriptiveType", then: COUNT, other: COUNT },
|
||||
};
|
||||
|
||||
const REPORT = {
|
||||
@ -49,7 +50,8 @@ function run_test() {
|
||||
count: 1,
|
||||
bytes: 10
|
||||
}
|
||||
}
|
||||
},
|
||||
domNode: {}
|
||||
};
|
||||
|
||||
const EXPECTED = {
|
||||
@ -73,8 +75,8 @@ function run_test() {
|
||||
totalBytes: 70,
|
||||
count: 7,
|
||||
totalCount: 7,
|
||||
id: 13,
|
||||
parent: 12,
|
||||
id: 14,
|
||||
parent: 13,
|
||||
children: undefined,
|
||||
reportLeafIndex: 2,
|
||||
},
|
||||
@ -84,18 +86,18 @@ function run_test() {
|
||||
totalBytes: 60,
|
||||
count: 6,
|
||||
totalCount: 6,
|
||||
id: 14,
|
||||
parent: 12,
|
||||
id: 15,
|
||||
parent: 13,
|
||||
children: undefined,
|
||||
reportLeafIndex: 3,
|
||||
},
|
||||
],
|
||||
id: 12,
|
||||
parent: 11,
|
||||
id: 13,
|
||||
parent: 12,
|
||||
reportLeafIndex: undefined,
|
||||
}
|
||||
],
|
||||
id: 11,
|
||||
id: 12,
|
||||
reportLeafIndex: undefined,
|
||||
};
|
||||
|
||||
|
@ -28,6 +28,10 @@ function run_test() {
|
||||
by: "internalType",
|
||||
then: { by: "count", count: true, bytes: true },
|
||||
},
|
||||
domNode: {
|
||||
by: "descriptiveType",
|
||||
then: { by: "count", count: true, bytes: true },
|
||||
},
|
||||
};
|
||||
|
||||
const REPORT = {
|
||||
@ -53,6 +57,7 @@ function run_test() {
|
||||
"js::Shape": { count: 7, bytes: 70 },
|
||||
"js::BaseShape": { count: 1, bytes: 10 },
|
||||
},
|
||||
domNode: { },
|
||||
};
|
||||
|
||||
const root = censusReportToCensusTreeNode(BREAKDOWN, REPORT);
|
||||
|
265
docshell/base/BrowsingContext.cpp
Normal file
265
docshell/base/BrowsingContext.cpp
Normal file
@ -0,0 +1,265 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "BrowsingContext.h"
|
||||
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "mozilla/Logging.h"
|
||||
#include "mozilla/StaticPtr.h"
|
||||
|
||||
#include "nsDataHashtable.h"
|
||||
#include "nsRefPtrHashtable.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
static LazyLogModule gBrowsingContextLog("BrowsingContext");
|
||||
|
||||
static StaticAutoPtr<BrowsingContext::Children> sRootBrowsingContexts;
|
||||
|
||||
static StaticAutoPtr<nsDataHashtable<nsUint64HashKey, BrowsingContext*>>
|
||||
sBrowsingContexts;
|
||||
|
||||
// TODO(farre): This duplicates some of the work performed by the
|
||||
// bfcache. This should be unified. [Bug 1471601]
|
||||
static StaticAutoPtr<nsRefPtrHashtable<nsUint64HashKey, BrowsingContext>>
|
||||
sCachedBrowsingContexts;
|
||||
|
||||
/* static */ void
|
||||
BrowsingContext::Init()
|
||||
{
|
||||
if (!sRootBrowsingContexts) {
|
||||
sRootBrowsingContexts = new BrowsingContext::Children();
|
||||
ClearOnShutdown(&sRootBrowsingContexts);
|
||||
}
|
||||
|
||||
if (!sBrowsingContexts) {
|
||||
sBrowsingContexts =
|
||||
new nsDataHashtable<nsUint64HashKey, BrowsingContext*>();
|
||||
ClearOnShutdown(&sBrowsingContexts);
|
||||
}
|
||||
|
||||
if (!sCachedBrowsingContexts) {
|
||||
sCachedBrowsingContexts =
|
||||
new nsRefPtrHashtable<nsUint64HashKey, BrowsingContext>();
|
||||
ClearOnShutdown(&sCachedBrowsingContexts);
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ LogModule*
|
||||
BrowsingContext::GetLog()
|
||||
{
|
||||
return gBrowsingContextLog;
|
||||
}
|
||||
|
||||
// TODO(farre): BrowsingContext::CleanupContexts starts from the list
|
||||
// of root BrowsingContexts. This isn't enough when separate
|
||||
// BrowsingContext nodes of a BrowsingContext tree not in a crashing
|
||||
// child process are from that process and thus needs to be
|
||||
// cleaned. [Bug 1472108]
|
||||
/* static */ void
|
||||
BrowsingContext::CleanupContexts(uint64_t aProcessId)
|
||||
{
|
||||
if (sRootBrowsingContexts) {
|
||||
RefPtr<BrowsingContext> context = sRootBrowsingContexts->getFirst();
|
||||
|
||||
while (context) {
|
||||
RefPtr<BrowsingContext> next = context->getNext();
|
||||
if (context->IsOwnedByProcess() &&
|
||||
aProcessId == context->OwnerProcessId()) {
|
||||
context->Detach();
|
||||
}
|
||||
context = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<BrowsingContext>
|
||||
BrowsingContext::Get(uint64_t aId)
|
||||
{
|
||||
RefPtr<BrowsingContext> abc = sBrowsingContexts->Get(aId);
|
||||
return abc.forget();
|
||||
}
|
||||
|
||||
BrowsingContext::BrowsingContext(nsIDocShell* aDocShell)
|
||||
: mBrowsingContextId(nsContentUtils::GenerateBrowsingContextId())
|
||||
, mProcessId(Nothing())
|
||||
, mDocShell(aDocShell)
|
||||
{
|
||||
sBrowsingContexts->Put(mBrowsingContextId, this);
|
||||
}
|
||||
|
||||
BrowsingContext::BrowsingContext(uint64_t aBrowsingContextId,
|
||||
const nsAString& aName,
|
||||
const Maybe<uint64_t>& aProcessId)
|
||||
: mBrowsingContextId(aBrowsingContextId)
|
||||
, mProcessId(aProcessId)
|
||||
, mName(aName)
|
||||
{
|
||||
// mProcessId only really has a meaning in the parent process, where
|
||||
// it keeps track of which BrowsingContext is actually holding the
|
||||
// nsDocShell.
|
||||
MOZ_DIAGNOSTIC_ASSERT(XRE_IsParentProcess() || aProcessId.isNothing());
|
||||
sBrowsingContexts->Put(mBrowsingContextId, this);
|
||||
}
|
||||
|
||||
void
|
||||
BrowsingContext::Attach(BrowsingContext* aParent)
|
||||
{
|
||||
if (isInList()) {
|
||||
MOZ_LOG(GetLog(),
|
||||
LogLevel::Debug,
|
||||
("%s: Connecting already existing 0x%08" PRIx64 " to 0x%08" PRIx64,
|
||||
XRE_IsParentProcess() ? "Parent" : "Child",
|
||||
Id(),
|
||||
aParent ? aParent->Id() : 0));
|
||||
MOZ_DIAGNOSTIC_ASSERT(sBrowsingContexts->Contains(Id()));
|
||||
MOZ_DIAGNOSTIC_ASSERT(!IsCached());
|
||||
return;
|
||||
}
|
||||
|
||||
bool wasCached = sCachedBrowsingContexts->Remove(Id());
|
||||
|
||||
MOZ_LOG(GetLog(),
|
||||
LogLevel::Debug,
|
||||
("%s: %s 0x%08" PRIx64 " to 0x%08" PRIx64,
|
||||
wasCached ? "Re-connecting" : "Connecting",
|
||||
XRE_IsParentProcess() ? "Parent" : "Child",
|
||||
Id(),
|
||||
aParent ? aParent->Id() : 0));
|
||||
|
||||
auto* children = aParent ? &aParent->mChildren : sRootBrowsingContexts.get();
|
||||
children->insertBack(this);
|
||||
mParent = aParent;
|
||||
|
||||
if (!XRE_IsContentProcess()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto cc = dom::ContentChild::GetSingleton();
|
||||
MOZ_DIAGNOSTIC_ASSERT(cc);
|
||||
cc->SendAttachBrowsingContext(
|
||||
dom::BrowsingContextId(mParent ? mParent->Id() : 0),
|
||||
dom::BrowsingContextId(Id()),
|
||||
mName);
|
||||
}
|
||||
|
||||
void
|
||||
BrowsingContext::Detach()
|
||||
{
|
||||
RefPtr<BrowsingContext> kungFuDeathGrip(this);
|
||||
|
||||
if (sCachedBrowsingContexts) {
|
||||
sCachedBrowsingContexts->Remove(Id());
|
||||
}
|
||||
|
||||
if (!isInList()) {
|
||||
MOZ_LOG(GetLog(),
|
||||
LogLevel::Debug,
|
||||
("%s: Detaching already detached 0x%08" PRIx64,
|
||||
XRE_IsParentProcess() ? "Parent" : "Child",
|
||||
Id()));
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_LOG(GetLog(),
|
||||
LogLevel::Debug,
|
||||
("%s: Detaching 0x%08" PRIx64 " from 0x%08" PRIx64,
|
||||
XRE_IsParentProcess() ? "Parent" : "Child",
|
||||
Id(),
|
||||
mParent ? mParent->Id() : 0));
|
||||
|
||||
remove();
|
||||
|
||||
if (!XRE_IsContentProcess()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto cc = dom::ContentChild::GetSingleton();
|
||||
MOZ_DIAGNOSTIC_ASSERT(cc);
|
||||
cc->SendDetachBrowsingContext(dom::BrowsingContextId(Id()),
|
||||
false /* aMoveToBFCache */);
|
||||
}
|
||||
|
||||
void
|
||||
BrowsingContext::CacheChildren()
|
||||
{
|
||||
if (mChildren.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_LOG(GetLog(),
|
||||
LogLevel::Debug,
|
||||
("%s: Caching children of 0x%08" PRIx64 "",
|
||||
XRE_IsParentProcess() ? "Parent" : "Child",
|
||||
Id()));
|
||||
|
||||
while (!mChildren.isEmpty()) {
|
||||
RefPtr<BrowsingContext> child = mChildren.popFirst();
|
||||
sCachedBrowsingContexts->Put(child->Id(), child);
|
||||
}
|
||||
|
||||
if (!XRE_IsContentProcess()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto cc = dom::ContentChild::GetSingleton();
|
||||
MOZ_DIAGNOSTIC_ASSERT(cc);
|
||||
cc->SendDetachBrowsingContext(dom::BrowsingContextId(Id()),
|
||||
true /* aMoveToBFCache */);
|
||||
}
|
||||
|
||||
bool
|
||||
BrowsingContext::IsCached()
|
||||
{
|
||||
return sCachedBrowsingContexts->Contains(Id());
|
||||
}
|
||||
|
||||
uint64_t
|
||||
BrowsingContext::OwnerProcessId() const
|
||||
{
|
||||
MOZ_DIAGNOSTIC_ASSERT(XRE_IsParentProcess());
|
||||
return mProcessId.value();
|
||||
}
|
||||
|
||||
BrowsingContext::~BrowsingContext()
|
||||
{
|
||||
MOZ_DIAGNOSTIC_ASSERT(!isInList());
|
||||
|
||||
if (sBrowsingContexts) {
|
||||
sBrowsingContexts->Remove(mBrowsingContextId);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ImplCycleCollectionUnlink(BrowsingContext::Children& aField)
|
||||
{
|
||||
aField.clear();
|
||||
}
|
||||
|
||||
static void
|
||||
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
|
||||
BrowsingContext::Children& aField,
|
||||
const char* aName,
|
||||
uint32_t aFlags = 0)
|
||||
{
|
||||
for (BrowsingContext* aContext : aField) {
|
||||
aCallback.NoteNativeChild(aContext,
|
||||
NS_CYCLE_COLLECTION_PARTICIPANT(BrowsingContext));
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION(BrowsingContext, mDocShell, mChildren)
|
||||
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(BrowsingContext, AddRef)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(BrowsingContext, Release)
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
109
docshell/base/BrowsingContext.h
Normal file
109
docshell/base/BrowsingContext.h
Normal file
@ -0,0 +1,109 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef BrowsingContext_h
|
||||
#define BrowsingContext_h
|
||||
|
||||
#include "mozilla/LinkedList.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/WeakPtr.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsString.h"
|
||||
|
||||
class nsIDocShell;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class LogModule;
|
||||
|
||||
namespace dom {
|
||||
|
||||
// BrowsingContext, in this context, is the cross process replicated
|
||||
// environment in which information about documents is stored. In
|
||||
// particular the tree structure of nested browsing contexts is
|
||||
// represented by the tree of BrowsingContexts.
|
||||
//
|
||||
// The tree of BrowsingContexts in created in step with its
|
||||
// corresponding nsDocShell, and when nsDocShells are connected
|
||||
// through a parent/child relationship, so are BrowsingContexts. The
|
||||
// major difference is that BrowsingContexts are replicated (synced)
|
||||
// to the parent process, making it possible to traverse the
|
||||
// BrowsingContext tree for a tab, in both the parent and the child
|
||||
// process.
|
||||
class BrowsingContext
|
||||
: public SupportsWeakPtr<BrowsingContext>
|
||||
, public LinkedListElement<RefPtr<BrowsingContext>>
|
||||
{
|
||||
public:
|
||||
static void Init();
|
||||
static LogModule* GetLog();
|
||||
static void CleanupContexts(uint64_t aProcessId);
|
||||
|
||||
static already_AddRefed<BrowsingContext> Get(uint64_t aId);
|
||||
|
||||
// Create a new BrowsingContext for 'aDocShell'. The id will be
|
||||
// generated so that it is unique across all content child processes
|
||||
// and the content parent process.
|
||||
explicit BrowsingContext(nsIDocShell* aDocShell);
|
||||
// Create a BrowsingContext for a particular BrowsingContext id, in
|
||||
// the case where the id is known beforehand and a nsDocShell isn't
|
||||
// needed (e.g. when creating BrowsingContexts in the parent
|
||||
// process).
|
||||
BrowsingContext(uint64_t aBrowsingContextId,
|
||||
const nsAString& aName,
|
||||
const Maybe<uint64_t>& aProcessId = Nothing());
|
||||
|
||||
// Attach the current BrowsingContext to its parent, in both the
|
||||
// child and the parent process. If 'aParent' is null, 'this' is
|
||||
// taken to be a root BrowsingContext.
|
||||
void Attach(BrowsingContext* aParent);
|
||||
|
||||
// Detach the current BrowsingContext from its parent, in both the
|
||||
// child and the parent process.
|
||||
void Detach();
|
||||
|
||||
// Remove all children from the current BrowsingContext and cache
|
||||
// them to allow them to be attached again.
|
||||
void CacheChildren();
|
||||
|
||||
bool IsCached();
|
||||
|
||||
void SetName(const nsAString& aName) { mName = aName; }
|
||||
void GetName(nsAString& aName) { aName = mName; }
|
||||
bool NameEquals(const nsAString& aName) { return mName.Equals(aName); }
|
||||
|
||||
uint64_t Id() const { return mBrowsingContextId; }
|
||||
uint64_t OwnerProcessId() const;
|
||||
bool IsOwnedByProcess() const { return mProcessId.isSome(); }
|
||||
|
||||
BrowsingContext* Parent() const { return mParent; }
|
||||
|
||||
MOZ_DECLARE_WEAKREFERENCE_TYPENAME(BrowsingContext)
|
||||
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(BrowsingContext)
|
||||
NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(BrowsingContext)
|
||||
|
||||
using Children = AutoCleanLinkedList<RefPtr<BrowsingContext>>;
|
||||
|
||||
private:
|
||||
~BrowsingContext();
|
||||
|
||||
const uint64_t mBrowsingContextId;
|
||||
|
||||
// Indicates which process owns the docshell. Only valid in the
|
||||
// parent process.
|
||||
Maybe<uint64_t> mProcessId;
|
||||
|
||||
WeakPtr<BrowsingContext> mParent;
|
||||
Children mChildren;
|
||||
nsCOMPtr<nsIDocShell> mDocShell;
|
||||
nsString mName;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
#endif
|
@ -77,7 +77,12 @@ EXPORTS.mozilla += [
|
||||
'LoadContext.h',
|
||||
]
|
||||
|
||||
EXPORTS.mozilla.dom += [
|
||||
'BrowsingContext.h',
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'BrowsingContext.cpp',
|
||||
'LoadContext.cpp',
|
||||
'nsAboutRedirector.cpp',
|
||||
'nsDefaultURIFixup.cpp',
|
||||
|
@ -475,6 +475,8 @@ nsDocShell::Init()
|
||||
rv = nsDocLoader::AddDocLoaderAsChildOfRoot(this);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mBrowsingContext = new BrowsingContext(this);
|
||||
|
||||
// Add as |this| a progress listener to itself. A little weird, but
|
||||
// simpler than reproducing all the listener-notification logic in
|
||||
// overrides of the various methods via which nsDocLoader can be
|
||||
@ -505,7 +507,8 @@ NS_IMPL_CYCLE_COLLECTION_INHERITED(nsDocShell,
|
||||
mSessionStorageManager,
|
||||
mScriptGlobal,
|
||||
mInitialClientSource,
|
||||
mSessionHistory)
|
||||
mSessionHistory,
|
||||
mBrowsingContext)
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(nsDocShell, nsDocLoader)
|
||||
NS_IMPL_RELEASE_INHERITED(nsDocShell, nsDocLoader)
|
||||
@ -2539,14 +2542,14 @@ nsDocShell::NotifyScrollObservers()
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::GetName(nsAString& aName)
|
||||
{
|
||||
aName = mName;
|
||||
mBrowsingContext->GetName(aName);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::SetName(const nsAString& aName)
|
||||
{
|
||||
mName = aName;
|
||||
mBrowsingContext->SetName(aName);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -2554,7 +2557,7 @@ NS_IMETHODIMP
|
||||
nsDocShell::NameEquals(const nsAString& aName, bool* aResult)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
*aResult = mName.Equals(aName);
|
||||
*aResult = mBrowsingContext->NameEquals(aName);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -2851,6 +2854,7 @@ nsDocShell::SetDocLoaderParent(nsDocLoader* aParent)
|
||||
bool value;
|
||||
nsString customUserAgent;
|
||||
nsCOMPtr<nsIDocShell> parentAsDocShell(do_QueryInterface(parent));
|
||||
|
||||
if (parentAsDocShell) {
|
||||
if (mAllowPlugins && NS_SUCCEEDED(parentAsDocShell->GetAllowPlugins(&value))) {
|
||||
SetAllowPlugins(value);
|
||||
@ -3259,7 +3263,7 @@ nsDocShell::DoFindItemWithName(const nsAString& aName,
|
||||
nsIDocShellTreeItem** aResult)
|
||||
{
|
||||
// First we check our name.
|
||||
if (mName.Equals(aName) && ItemIsActive(this) &&
|
||||
if (mBrowsingContext->NameEquals(aName) && ItemIsActive(this) &&
|
||||
CanAccessItem(this, aOriginalRequestor)) {
|
||||
NS_ADDREF(*aResult = this);
|
||||
return NS_OK;
|
||||
@ -3550,6 +3554,8 @@ nsDocShell::AddChild(nsIDocShellTreeItem* aChild)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
childAsDocShell->AttachBrowsingContext(this);
|
||||
|
||||
// charset, style-disabling, and zoom will be inherited in SetupNewViewer()
|
||||
|
||||
// Now take this document's charset and set the child's parentCharset field
|
||||
@ -3612,6 +3618,11 @@ nsDocShell::RemoveChild(nsIDocShellTreeItem* aChild)
|
||||
nsresult rv = RemoveChildLoader(childAsDocLoader);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIDocShell> childAsDocShell(do_QueryInterface(aChild));
|
||||
if (childAsDocShell) {
|
||||
childAsDocShell->DetachBrowsingContext();
|
||||
}
|
||||
|
||||
aChild->SetTreeOwner(nullptr);
|
||||
|
||||
return nsDocLoader::AddDocLoaderAsChildOfRoot(childAsDocLoader);
|
||||
@ -5290,6 +5301,8 @@ nsDocShell::Destroy()
|
||||
mSessionHistory = nullptr;
|
||||
}
|
||||
|
||||
mBrowsingContext->Detach();
|
||||
|
||||
SetTreeOwner(nullptr);
|
||||
|
||||
mOnePermittedSandboxedNavigator = nullptr;
|
||||
@ -7750,6 +7763,8 @@ nsDocShell::CaptureState()
|
||||
mOSHE->AddChildShell(childShell);
|
||||
}
|
||||
|
||||
mBrowsingContext->CacheChildren();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -14223,3 +14238,31 @@ nsDocShell::IsForceReloading()
|
||||
{
|
||||
return IsForceReloadType(mLoadType);
|
||||
}
|
||||
|
||||
already_AddRefed<BrowsingContext>
|
||||
nsDocShell::GetBrowsingContext() const
|
||||
{
|
||||
RefPtr<BrowsingContext> browsingContext = mBrowsingContext;
|
||||
return browsingContext.forget();
|
||||
}
|
||||
|
||||
void
|
||||
nsIDocShell::AttachBrowsingContext(nsIDocShell* aParentDocShell)
|
||||
{
|
||||
RefPtr<BrowsingContext> childContext =
|
||||
nsDocShell::Cast(this)->GetBrowsingContext();
|
||||
RefPtr<BrowsingContext> parentContext;
|
||||
if (aParentDocShell) {
|
||||
parentContext =
|
||||
nsDocShell::Cast(aParentDocShell)->GetBrowsingContext();
|
||||
}
|
||||
childContext->Attach(parentContext);
|
||||
}
|
||||
|
||||
void
|
||||
nsIDocShell::DetachBrowsingContext()
|
||||
{
|
||||
RefPtr<BrowsingContext> browsingContext =
|
||||
nsDocShell::Cast(this)->GetBrowsingContext();
|
||||
browsingContext->Detach();
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/WeakPtr.h"
|
||||
|
||||
#include "mozilla/dom/BrowsingContext.h"
|
||||
#include "mozilla/dom/ProfileTimelineMarkerBinding.h"
|
||||
#include "mozilla/gfx/Matrix.h"
|
||||
#include "mozilla/dom/ChildSHistory.h"
|
||||
@ -379,6 +380,9 @@ public:
|
||||
// shift while triggering reload)
|
||||
bool IsForceReloading();
|
||||
|
||||
already_AddRefed<mozilla::dom::BrowsingContext>
|
||||
GetBrowsingContext() const;
|
||||
|
||||
private: // member functions
|
||||
friend class nsDSURIContentListener;
|
||||
friend class FramingChecker;
|
||||
@ -907,7 +911,6 @@ private: // data members
|
||||
#endif /* DEBUG */
|
||||
|
||||
nsID mHistoryID;
|
||||
nsString mName;
|
||||
nsString mTitle;
|
||||
nsString mCustomUserAgent;
|
||||
nsCString mOriginalUriString;
|
||||
@ -932,6 +935,7 @@ private: // data members
|
||||
RefPtr<mozilla::dom::ChildSHistory> mSessionHistory;
|
||||
nsCOMPtr<nsIWebBrowserFind> mFind;
|
||||
nsCOMPtr<nsICommandManager> mCommandManager;
|
||||
RefPtr<mozilla::dom::BrowsingContext> mBrowsingContext;
|
||||
|
||||
// Dimensions of the docshell
|
||||
nsIntRect mBounds;
|
||||
|
@ -22,6 +22,7 @@ namespace mozilla {
|
||||
class Encoding;
|
||||
class HTMLEditor;
|
||||
namespace dom {
|
||||
class BrowsingContext;
|
||||
class ClientSource;
|
||||
} // namespace dom
|
||||
}
|
||||
@ -1180,6 +1181,9 @@ interface nsIDocShell : nsIDocShellTreeItem
|
||||
*/
|
||||
mozilla::HTMLEditor* GetHTMLEditor();
|
||||
nsresult SetHTMLEditor(mozilla::HTMLEditor* aHTMLEditor);
|
||||
|
||||
void AttachBrowsingContext(nsIDocShell* aParentDocShell);
|
||||
void DetachBrowsingContext();
|
||||
%}
|
||||
|
||||
/**
|
||||
|
@ -7,6 +7,8 @@
|
||||
#include "mozilla/ModuleUtils.h"
|
||||
#include "nsDocShellCID.h"
|
||||
|
||||
#include "mozilla/dom/BrowsingContext.h"
|
||||
|
||||
#include "nsDocShell.h"
|
||||
#include "nsDefaultURIFixup.h"
|
||||
#include "nsWebNavigationInfo.h"
|
||||
@ -53,6 +55,7 @@ Initialize()
|
||||
}
|
||||
gInitialized = true;
|
||||
|
||||
mozilla::dom::BrowsingContext::Init();
|
||||
nsresult rv = nsSHistory::Startup();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
@ -1178,24 +1178,18 @@ Navigator::MozGetUserMedia(const MediaStreamConstraints& aConstraints,
|
||||
CallerType aCallerType,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
CallbackObjectHolder<NavigatorUserMediaSuccessCallback,
|
||||
nsIDOMGetUserMediaSuccessCallback> holder1(&aOnSuccess);
|
||||
nsCOMPtr<nsIDOMGetUserMediaSuccessCallback> onsuccess =
|
||||
holder1.ToXPCOMCallback();
|
||||
|
||||
CallbackObjectHolder<NavigatorUserMediaErrorCallback,
|
||||
nsIDOMGetUserMediaErrorCallback> holder2(&aOnError);
|
||||
nsCOMPtr<nsIDOMGetUserMediaErrorCallback> onerror = holder2.ToXPCOMCallback();
|
||||
|
||||
if (!mWindow || !mWindow->GetOuterWindow() ||
|
||||
mWindow->GetOuterWindow()->GetCurrentInnerWindow() != mWindow) {
|
||||
aRv.Throw(NS_ERROR_NOT_AVAILABLE);
|
||||
return;
|
||||
}
|
||||
|
||||
MediaManager::GetUserMediaSuccessCallback onsuccess(&aOnSuccess);
|
||||
MediaManager::GetUserMediaErrorCallback onerror(&aOnError);
|
||||
|
||||
MediaManager* manager = MediaManager::Get();
|
||||
aRv = manager->GetUserMedia(mWindow, aConstraints, onsuccess, onerror,
|
||||
aCallerType);
|
||||
aRv = manager->GetUserMedia(mWindow, aConstraints, std::move(onsuccess),
|
||||
std::move(onerror), aCallerType);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1206,15 +1200,6 @@ Navigator::MozGetUserMediaDevices(const MediaStreamConstraints& aConstraints,
|
||||
const nsAString& aCallID,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
CallbackObjectHolder<MozGetUserMediaDevicesSuccessCallback,
|
||||
nsIGetUserMediaDevicesSuccessCallback> holder1(&aOnSuccess);
|
||||
nsCOMPtr<nsIGetUserMediaDevicesSuccessCallback> onsuccess =
|
||||
holder1.ToXPCOMCallback();
|
||||
|
||||
CallbackObjectHolder<NavigatorUserMediaErrorCallback,
|
||||
nsIDOMGetUserMediaErrorCallback> holder2(&aOnError);
|
||||
nsCOMPtr<nsIDOMGetUserMediaErrorCallback> onerror = holder2.ToXPCOMCallback();
|
||||
|
||||
if (!mWindow || !mWindow->GetOuterWindow() ||
|
||||
mWindow->GetOuterWindow()->GetCurrentInnerWindow() != mWindow) {
|
||||
aRv.Throw(NS_ERROR_NOT_AVAILABLE);
|
||||
@ -1222,7 +1207,8 @@ Navigator::MozGetUserMediaDevices(const MediaStreamConstraints& aConstraints,
|
||||
}
|
||||
|
||||
MediaManager* manager = MediaManager::Get();
|
||||
aRv = manager->GetUserMediaDevices(mWindow, aConstraints, onsuccess, onerror,
|
||||
// XXXbz aOnError seems to be unused?
|
||||
aRv = manager->GetUserMediaDevices(mWindow, aConstraints, aOnSuccess,
|
||||
aInnerWindowID, aCallID);
|
||||
}
|
||||
|
||||
|
@ -64,6 +64,12 @@ JS::ubi::Concrete<nsINode>::size(mozilla::MallocSizeOf mallocSizeOf) const
|
||||
return n;
|
||||
}
|
||||
|
||||
const char16_t*
|
||||
JS::ubi::Concrete<nsINode>::descriptiveTypeName() const
|
||||
{
|
||||
return get().NodeName().get();
|
||||
}
|
||||
|
||||
JS::ubi::Node::Size
|
||||
JS::ubi::Concrete<nsIDocument>::size(mozilla::MallocSizeOf mallocSizeOf) const
|
||||
{
|
||||
|
@ -36,7 +36,8 @@ public:
|
||||
js::UniquePtr<EdgeRange> edges(JSContext* cx, bool wantNames) const override;
|
||||
|
||||
nsINode& get() const { return *static_cast<nsINode*>(ptr); }
|
||||
CoarseType coarseType() const final { return CoarseType::Other; }
|
||||
CoarseType coarseType() const final { return CoarseType::DOMNode; }
|
||||
const char16_t* descriptiveTypeName() const override;
|
||||
};
|
||||
|
||||
template<>
|
||||
|
@ -10800,13 +10800,11 @@ nsContentUtils::IsLocalRefURL(const nsACString& aString)
|
||||
return ::IsLocalRefURL(aString);
|
||||
}
|
||||
|
||||
// Tab ID is composed in a similar manner of Window ID.
|
||||
static uint64_t gNextTabId = 0;
|
||||
static const uint64_t kTabIdProcessBits = 32;
|
||||
static const uint64_t kTabIdTabBits = 64 - kTabIdProcessBits;
|
||||
static const uint64_t kIdProcessBits = 32;
|
||||
static const uint64_t kIdBits = 64 - kIdProcessBits;
|
||||
|
||||
/* static */ uint64_t
|
||||
nsContentUtils::GenerateTabId()
|
||||
GenerateProcessSpecificId(uint64_t aId)
|
||||
{
|
||||
uint64_t processId = 0;
|
||||
if (XRE_IsContentProcess()) {
|
||||
@ -10814,14 +10812,32 @@ nsContentUtils::GenerateTabId()
|
||||
processId = cc->GetID();
|
||||
}
|
||||
|
||||
MOZ_RELEASE_ASSERT(processId < (uint64_t(1) << kTabIdProcessBits));
|
||||
uint64_t processBits = processId & ((uint64_t(1) << kTabIdProcessBits) - 1);
|
||||
MOZ_RELEASE_ASSERT(processId < (uint64_t(1) << kIdProcessBits));
|
||||
uint64_t processBits = processId & ((uint64_t(1) << kIdProcessBits) - 1);
|
||||
|
||||
uint64_t tabId = ++gNextTabId;
|
||||
MOZ_RELEASE_ASSERT(tabId < (uint64_t(1) << kTabIdTabBits));
|
||||
uint64_t tabBits = tabId & ((uint64_t(1) << kTabIdTabBits) - 1);
|
||||
uint64_t id = aId;
|
||||
MOZ_RELEASE_ASSERT(id < (uint64_t(1) << kIdBits));
|
||||
uint64_t bits = id & ((uint64_t(1) << kIdBits) - 1);
|
||||
|
||||
return (processBits << kTabIdTabBits) | tabBits;
|
||||
return (processBits << kIdBits) | bits;
|
||||
}
|
||||
|
||||
// Tab ID is composed in a similar manner of Window ID.
|
||||
static uint64_t gNextTabId = 0;
|
||||
|
||||
/* static */ uint64_t
|
||||
nsContentUtils::GenerateTabId()
|
||||
{
|
||||
return GenerateProcessSpecificId(++gNextTabId);
|
||||
}
|
||||
|
||||
// Browsing context ID is composed in a similar manner of Window ID.
|
||||
static uint64_t gNextBrowsingContextId = 0;
|
||||
|
||||
/* static */ uint64_t
|
||||
nsContentUtils::GenerateBrowsingContextId()
|
||||
{
|
||||
return GenerateProcessSpecificId(++gNextBrowsingContextId);
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
|
@ -3166,6 +3166,12 @@ public:
|
||||
*/
|
||||
static uint64_t GenerateTabId();
|
||||
|
||||
/**
|
||||
* Generate an id for a BrowsingContext using a range of serial
|
||||
* numbers reserved for the current process.
|
||||
*/
|
||||
static uint64_t GenerateBrowsingContextId();
|
||||
|
||||
/**
|
||||
* Check whether we should skip moving the cursor for a same-value .value set
|
||||
* on a text input or textarea.
|
||||
|
@ -689,6 +689,8 @@ nsFrameLoader::AddTreeItemToTreeOwner(nsIDocShellTreeItem* aItem,
|
||||
// Now that we have our type set, add ourselves to the parent, as needed.
|
||||
if (aParentNode) {
|
||||
aParentNode->AddChild(aItem);
|
||||
} else if (nsCOMPtr<nsIDocShell> childAsDocShell = do_QueryInterface(aItem)) {
|
||||
childAsDocShell->AttachBrowsingContext(aParentNode);
|
||||
}
|
||||
|
||||
bool retval = false;
|
||||
|
@ -433,11 +433,25 @@ public:
|
||||
|
||||
void operator=(const CallbackObjectHolder& aOther) = delete;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
UnlinkSelf();
|
||||
}
|
||||
|
||||
nsISupports* GetISupports() const
|
||||
{
|
||||
return reinterpret_cast<nsISupports*>(mPtrBits & ~XPCOMCallbackFlag);
|
||||
}
|
||||
|
||||
already_AddRefed<nsISupports> Forget()
|
||||
{
|
||||
// This can be called from random threads. Make sure to not refcount things
|
||||
// in here!
|
||||
nsISupports* supp = GetISupports();
|
||||
mPtrBits = 0;
|
||||
return dont_AddRef(supp);
|
||||
}
|
||||
|
||||
// Boolean conversion operator so people can use this in boolean tests
|
||||
explicit operator bool() const
|
||||
{
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "js/Wrapper.h"
|
||||
#include "jsapi.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/HashFunctions.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
@ -92,7 +93,7 @@ struct WebIDLNameTableEntry : public PLDHashEntryHdr
|
||||
const char* name = WebIDLGlobalNameHash::sNames + mNameOffset;
|
||||
|
||||
if (aKey->mLatin1String) {
|
||||
return PodEqual(aKey->mLatin1String, name, aKey->mLength);
|
||||
return ArrayEqual(aKey->mLatin1String, name, aKey->mLength);
|
||||
}
|
||||
|
||||
return nsCharTraits<char16_t>::compareASCII(aKey->mTwoBytesString, name,
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "mozilla/DataStorage.h"
|
||||
#include "mozilla/devtools/HeapSnapshotTempFileHelperParent.h"
|
||||
#include "mozilla/docshell/OfflineCacheUpdateParent.h"
|
||||
#include "mozilla/dom/BrowsingContext.h"
|
||||
#include "mozilla/dom/ClientManager.h"
|
||||
#include "mozilla/dom/ClientOpenWindowOpActors.h"
|
||||
#include "mozilla/dom/DataTransfer.h"
|
||||
@ -1895,6 +1896,8 @@ ContentParent::ActorDestroy(ActorDestroyReason why)
|
||||
#if defined(XP_WIN32) && defined(ACCESSIBILITY)
|
||||
a11y::AccessibleWrap::ReleaseContentProcessIdFor(ChildID());
|
||||
#endif
|
||||
|
||||
BrowsingContext::CleanupContexts(ChildID());
|
||||
}
|
||||
|
||||
bool
|
||||
@ -5977,3 +5980,114 @@ ContentParent::RecvFirstPartyStorageAccessGrantedForOrigin(const Principal& aPar
|
||||
std::move(aResolver));
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
ContentParent::RecvAttachBrowsingContext(
|
||||
const BrowsingContextId& aParentId,
|
||||
const BrowsingContextId& aChildId,
|
||||
const nsString& aName)
|
||||
{
|
||||
RefPtr<BrowsingContext> parent = BrowsingContext::Get(aParentId);
|
||||
if (aParentId && !parent) {
|
||||
// Unless 'aParentId' is 0 (which it is when the child is a root
|
||||
// BrowsingContext) there should always be a corresponding
|
||||
// 'parent'. The only reason for there not beeing one is if the
|
||||
// parent has already been detached, in which case the
|
||||
// BrowsingContext that tries to attach itself to the context with
|
||||
// 'aParentId' is surely doomed and we can safely do nothing.
|
||||
|
||||
// TODO(farre): When we start syncing/moving BrowsingContexts to
|
||||
// other child processes is it possible to get into races where
|
||||
// constructive operations on already detached BrowsingContexts
|
||||
// are requested? This needs to be answered/handled, but for now
|
||||
// return early. [Bug 1471598]
|
||||
MOZ_LOG(
|
||||
BrowsingContext::GetLog(),
|
||||
LogLevel::Debug,
|
||||
("ParentIPC: Trying to attach to already detached parent 0x%08" PRIx64,
|
||||
(uint64_t)aParentId));
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
if (parent && parent->OwnerProcessId() != ChildID()) {
|
||||
// Where trying attach a child BrowsingContext to a parent
|
||||
// BrowsingContext in another process. This is illegal since the
|
||||
// only thing that could create that child BrowsingContext is a
|
||||
// parent docshell in the same process as that BrowsingContext.
|
||||
|
||||
// TODO(farre): We're doing nothing now, but is that exactly what
|
||||
// we want? Maybe we want to crash the child currently calling
|
||||
// SendAttachBrowsingContext and/or the child that originally
|
||||
// called SendAttachBrowsingContext or possibly all children that
|
||||
// has a BrowsingContext connected to the child that currently
|
||||
// called SendAttachBrowsingContext? [Bug 1471598]
|
||||
MOZ_LOG(BrowsingContext::GetLog(),
|
||||
LogLevel::Warning,
|
||||
("ParentIPC: Trying to attach to out of process parent context "
|
||||
"0x%08" PRIx64,
|
||||
parent->Id()));
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
RefPtr<BrowsingContext> child = BrowsingContext::Get(aChildId);
|
||||
if (child && !child->IsCached()) {
|
||||
// This is highly suspicious. BrowsingContexts should only be
|
||||
// attached at most once, but finding one indicates that someone
|
||||
// is doing something they shouldn't.
|
||||
|
||||
// TODO(farre): To crash or not to crash. Same reasoning as in
|
||||
// above TODO. [Bug 1471598]
|
||||
MOZ_LOG(BrowsingContext::GetLog(),
|
||||
LogLevel::Warning,
|
||||
("ParentIPC: Trying to attach already attached 0x%08" PRIx64
|
||||
" to 0x%08" PRIx64,
|
||||
child->Id(),
|
||||
(uint64_t)aParentId));
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
if (!child) {
|
||||
child = new BrowsingContext(aChildId, aName, Some(ChildID()));
|
||||
}
|
||||
child->Attach(parent);
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
ContentParent::RecvDetachBrowsingContext(const BrowsingContextId& aContextId,
|
||||
const bool& aMoveToBFCache)
|
||||
{
|
||||
RefPtr<BrowsingContext> context = BrowsingContext::Get(aContextId);
|
||||
|
||||
if (!context) {
|
||||
MOZ_LOG(BrowsingContext::GetLog(),
|
||||
LogLevel::Debug,
|
||||
("ParentIPC: Trying to detach already detached 0x%08" PRIx64,
|
||||
(uint64_t)aContextId));
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
if (context->OwnerProcessId() != ChildID()) {
|
||||
// Where trying to detach a child BrowsingContext in another child
|
||||
// process. This is illegal since the owner of the BrowsingContext
|
||||
// is the proccess with the in-process docshell, which is tracked
|
||||
// by OwnerProcessId.
|
||||
|
||||
// TODO(farre): To crash or not to crash. Same reasoning as in
|
||||
// above TODO. [Bug 1471598]
|
||||
MOZ_LOG(BrowsingContext::GetLog(),
|
||||
LogLevel::Warning,
|
||||
("ParentIPC: Trying to detach out of process context 0x%08" PRIx64,
|
||||
context->Id()));
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
if (aMoveToBFCache) {
|
||||
context->CacheChildren();
|
||||
} else {
|
||||
context->Detach();
|
||||
}
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
@ -682,6 +682,15 @@ public:
|
||||
|
||||
static bool IsInputEventQueueSupported();
|
||||
|
||||
virtual mozilla::ipc::IPCResult RecvAttachBrowsingContext(
|
||||
const BrowsingContextId& aParentContextId,
|
||||
const BrowsingContextId& aContextId,
|
||||
const nsString& aName) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult RecvDetachBrowsingContext(
|
||||
const BrowsingContextId& aContextId,
|
||||
const bool& aMoveToBFCache) override;
|
||||
|
||||
protected:
|
||||
void OnChannelConnected(int32_t pid) override;
|
||||
|
||||
|
@ -15,10 +15,10 @@ template<typename T> struct ParamTraits;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
class BrowsingContext;
|
||||
class ContentParent;
|
||||
class TabParent;
|
||||
|
||||
|
||||
template<typename T>
|
||||
class IdType
|
||||
{
|
||||
@ -46,7 +46,7 @@ private:
|
||||
|
||||
typedef IdType<TabParent> TabId;
|
||||
typedef IdType<ContentParent> ContentParentId;
|
||||
|
||||
typedef IdType<BrowsingContext> BrowsingContextId;
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
|
@ -100,6 +100,7 @@ using mozilla::Telemetry::ChildEventData from "mozilla/TelemetryComms.h";
|
||||
using mozilla::Telemetry::DiscardedData from "mozilla/TelemetryComms.h";
|
||||
using mozilla::CrossProcessMutexHandle from "mozilla/ipc/CrossProcessMutex.h";
|
||||
using refcounted class nsIInputStream from "mozilla/ipc/IPCStreamUtils.h";
|
||||
using mozilla::dom::BrowsingContextId from "mozilla/dom/ipc/IdType.h";
|
||||
|
||||
union ChromeRegistryItem
|
||||
{
|
||||
@ -1177,6 +1178,35 @@ parent:
|
||||
nsCString aGrantedOrigin)
|
||||
returns (bool unused);
|
||||
|
||||
/**
|
||||
* Sync the BrowsingContext with id 'aContextId' and name 'aName'
|
||||
* to the parent, and attach it to the BrowsingContext with id
|
||||
* 'aParentContextId'. If 'aParentContextId' is '0' the
|
||||
* BrowsingContext is a root in the BrowsingContext
|
||||
* tree. AttachBrowsingContext must only be called at most once
|
||||
* for any child BrowsingContext, and only for BrowsingContexts
|
||||
* where the parent and the child context contains their
|
||||
* nsDocShell.
|
||||
*/
|
||||
async AttachBrowsingContext(BrowsingContextId aParentContextId,
|
||||
BrowsingContextId aContextId,
|
||||
nsString aName);
|
||||
|
||||
/**
|
||||
* Remove the synced BrowsingContext with id 'aContextId' from the
|
||||
* parent. DetachBrowsingContext is only needed to be called once
|
||||
* for any BrowsingContext, since detaching a node in the
|
||||
* BrowsingContext detaches the entire sub-tree rooted at that
|
||||
* node. Calling DetachBrowsingContext with an already detached
|
||||
* BrowsingContext effectively does nothing. Note that it is not
|
||||
* an error to call DetachBrowsingContext on a BrowsingContext
|
||||
* belonging to an already detached subtree. The 'aMoveToBFCache'
|
||||
* paramater controls if detaching a BrowsingContext should move
|
||||
* it to the bfcache allowing it to be re-attached if navigated
|
||||
* to.
|
||||
*/
|
||||
async DetachBrowsingContext(BrowsingContextId aContextId,
|
||||
bool aMoveToBFCache);
|
||||
both:
|
||||
async AsyncMessage(nsString aMessage, CpowEntry[] aCpows,
|
||||
Principal aPrincipal, ClonedMessageData aData);
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "mozilla/dom/MediaStreamBinding.h"
|
||||
#include "mozilla/dom/MediaDeviceInfo.h"
|
||||
#include "mozilla/dom/MediaDevicesBinding.h"
|
||||
#include "mozilla/dom/NavigatorBinding.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "mozilla/MediaManager.h"
|
||||
#include "MediaTrackConstraints.h"
|
||||
@ -182,11 +183,12 @@ MediaDevices::GetUserMedia(const MediaStreamConstraints& aConstraints,
|
||||
RefPtr<Promise> p = Promise::Create(GetParentObject(), aRv);
|
||||
NS_ENSURE_TRUE(!aRv.Failed(), nullptr);
|
||||
|
||||
RefPtr<GumResolver> resolver = new GumResolver(p);
|
||||
RefPtr<GumRejecter> rejecter = new GumRejecter(p);
|
||||
MediaManager::GetUserMediaSuccessCallback resolver(new GumResolver(p));
|
||||
MediaManager::GetUserMediaErrorCallback rejecter(new GumRejecter(p));
|
||||
|
||||
aRv = MediaManager::Get()->GetUserMedia(GetOwner(), aConstraints,
|
||||
resolver, rejecter,
|
||||
std::move(resolver),
|
||||
std::move(rejecter),
|
||||
aCallerType);
|
||||
return p.forget();
|
||||
}
|
||||
|
@ -99,6 +99,77 @@ struct nsIMediaDevice::COMTypeInfo<mozilla::MediaDevice, void> {
|
||||
};
|
||||
const nsIID nsIMediaDevice::COMTypeInfo<mozilla::MediaDevice, void>::kIID = NS_IMEDIADEVICE_IID;
|
||||
|
||||
// A specialization of nsMainThreadPtrHolder for
|
||||
// mozilla::dom::CallbackObjectHolder. See documentation for
|
||||
// nsMainThreadPtrHolder in nsProxyRelease.h. This specialization lets us avoid
|
||||
// wrapping the CallbackObjectHolder into a separate refcounted object.
|
||||
template<class WebIDLCallbackT, class XPCOMCallbackT>
|
||||
class nsMainThreadPtrHolder<mozilla::dom::CallbackObjectHolder<WebIDLCallbackT,
|
||||
XPCOMCallbackT>> final
|
||||
{
|
||||
typedef mozilla::dom::CallbackObjectHolder<WebIDLCallbackT,
|
||||
XPCOMCallbackT> Holder;
|
||||
public:
|
||||
nsMainThreadPtrHolder(const char* aName, Holder&& aHolder)
|
||||
: mHolder(std::move(aHolder))
|
||||
#ifndef RELEASE_OR_BETA
|
||||
, mName(aName)
|
||||
#endif
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
}
|
||||
|
||||
private:
|
||||
// We can be released on any thread.
|
||||
~nsMainThreadPtrHolder()
|
||||
{
|
||||
if (NS_IsMainThread()) {
|
||||
mHolder.Reset();
|
||||
} else if (mHolder.GetISupports()) {
|
||||
nsCOMPtr<nsIEventTarget> target = do_GetMainThread();
|
||||
MOZ_ASSERT(target);
|
||||
NS_ProxyRelease(
|
||||
#ifdef RELEASE_OR_BETA
|
||||
nullptr,
|
||||
#else
|
||||
mName,
|
||||
#endif
|
||||
target, mHolder.Forget());
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
Holder* get()
|
||||
{
|
||||
// Nobody should be touching the raw pointer off-main-thread.
|
||||
if (MOZ_UNLIKELY(!NS_IsMainThread())) {
|
||||
NS_ERROR("Can't dereference nsMainThreadPtrHolder off main thread");
|
||||
MOZ_CRASH();
|
||||
}
|
||||
return &mHolder;
|
||||
}
|
||||
|
||||
bool operator!() const
|
||||
{
|
||||
return !mHolder;
|
||||
}
|
||||
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(nsMainThreadPtrHolder<Holder>)
|
||||
|
||||
private:
|
||||
// Our holder.
|
||||
Holder mHolder;
|
||||
|
||||
#ifndef RELEASE_OR_BETA
|
||||
const char* mName = nullptr;
|
||||
#endif
|
||||
|
||||
// Copy constructor and operator= not implemented. Once constructed, the
|
||||
// holder is immutable.
|
||||
Holder& operator=(const nsMainThreadPtrHolder& aOther) = delete;
|
||||
nsMainThreadPtrHolder(const nsMainThreadPtrHolder& aOther) = delete;
|
||||
};
|
||||
|
||||
namespace {
|
||||
already_AddRefed<nsIAsyncShutdownClient> GetShutdownPhase() {
|
||||
nsCOMPtr<nsIAsyncShutdownService> svc = mozilla::services::GetAsyncShutdown();
|
||||
@ -231,6 +302,30 @@ FromCaptureState(CaptureState aState)
|
||||
return static_cast<uint16_t>(aState);
|
||||
}
|
||||
|
||||
static void
|
||||
CallOnError(MediaManager::GetUserMediaErrorCallback* aCallback,
|
||||
MediaStreamError& aError)
|
||||
{
|
||||
MOZ_ASSERT(aCallback);
|
||||
if (aCallback->HasWebIDLCallback()) {
|
||||
aCallback->GetWebIDLCallback()->Call(aError);
|
||||
} else {
|
||||
aCallback->GetXPCOMCallback()->OnError(&aError);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
CallOnSuccess(MediaManager::GetUserMediaSuccessCallback* aCallback,
|
||||
DOMMediaStream& aStream)
|
||||
{
|
||||
MOZ_ASSERT(aCallback);
|
||||
if (aCallback->HasWebIDLCallback()) {
|
||||
aCallback->GetWebIDLCallback()->Call(aStream);
|
||||
} else {
|
||||
aCallback->GetXPCOMCallback()->OnSuccess(&aStream);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* SourceListener has threadsafe refcounting for use across the main, media and
|
||||
* MSG threads. But it has a non-threadsafe SupportsWeakPtr for WeakPtr usage
|
||||
@ -776,7 +871,7 @@ private:
|
||||
class ErrorCallbackRunnable : public Runnable
|
||||
{
|
||||
public:
|
||||
ErrorCallbackRunnable(const nsMainThreadPtrHandle<nsIDOMGetUserMediaErrorCallback>& aOnFailure,
|
||||
ErrorCallbackRunnable(const nsMainThreadPtrHandle<MediaManager::GetUserMediaErrorCallback>& aOnFailure,
|
||||
MediaMgrError& aError,
|
||||
uint64_t aWindowID)
|
||||
: Runnable("ErrorCallbackRunnable")
|
||||
@ -801,14 +896,14 @@ public:
|
||||
if (auto* window = nsGlobalWindowInner::GetInnerWindowWithId(mWindowID)) {
|
||||
RefPtr<MediaStreamError> error =
|
||||
new MediaStreamError(window->AsInner(), *mError);
|
||||
mOnFailure->OnError(error);
|
||||
CallOnError(mOnFailure, *error);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
private:
|
||||
~ErrorCallbackRunnable() override = default;
|
||||
|
||||
nsMainThreadPtrHandle<nsIDOMGetUserMediaErrorCallback> mOnFailure;
|
||||
nsMainThreadPtrHandle<MediaManager::GetUserMediaErrorCallback> mOnFailure;
|
||||
RefPtr<MediaMgrError> mError;
|
||||
uint64_t mWindowID;
|
||||
RefPtr<MediaManager> mManager; // get ref to this when creating the runnable
|
||||
@ -1164,8 +1259,8 @@ class GetUserMediaStreamRunnable : public Runnable
|
||||
{
|
||||
public:
|
||||
GetUserMediaStreamRunnable(
|
||||
const nsMainThreadPtrHandle<nsIDOMGetUserMediaSuccessCallback>& aOnSuccess,
|
||||
const nsMainThreadPtrHandle<nsIDOMGetUserMediaErrorCallback>& aOnFailure,
|
||||
const nsMainThreadPtrHandle<MediaManager::GetUserMediaSuccessCallback>& aOnSuccess,
|
||||
const nsMainThreadPtrHandle<MediaManager::GetUserMediaErrorCallback>& aOnFailure,
|
||||
uint64_t aWindowID,
|
||||
GetUserMediaWindowListener* aWindowListener,
|
||||
SourceListener* aSourceListener,
|
||||
@ -1196,7 +1291,7 @@ public:
|
||||
{
|
||||
public:
|
||||
TracksAvailableCallback(MediaManager* aManager,
|
||||
const nsMainThreadPtrHandle<nsIDOMGetUserMediaSuccessCallback>& aSuccess,
|
||||
const nsMainThreadPtrHandle<MediaManager::GetUserMediaSuccessCallback>& aSuccess,
|
||||
const RefPtr<GetUserMediaWindowListener>& aWindowListener,
|
||||
DOMMediaStream* aStream)
|
||||
: mWindowListener(aWindowListener),
|
||||
@ -1218,10 +1313,10 @@ public:
|
||||
// This is safe since we're on main-thread, and the windowlist can only
|
||||
// be invalidated from the main-thread (see OnNavigation)
|
||||
LOG(("Returning success for getUserMedia()"));
|
||||
mOnSuccess->OnSuccess(aStream);
|
||||
CallOnSuccess(mOnSuccess, *aStream);
|
||||
}
|
||||
RefPtr<GetUserMediaWindowListener> mWindowListener;
|
||||
nsMainThreadPtrHandle<nsIDOMGetUserMediaSuccessCallback> mOnSuccess;
|
||||
nsMainThreadPtrHandle<MediaManager::GetUserMediaSuccessCallback> mOnSuccess;
|
||||
RefPtr<MediaManager> mManager;
|
||||
// Keep the DOMMediaStream alive until the NotifyTracksAvailable callback
|
||||
// has fired, otherwise we might immediately destroy the DOMMediaStream and
|
||||
@ -1459,7 +1554,7 @@ public:
|
||||
MediaStreamError::Name::AbortError,
|
||||
sHasShutdown ? NS_LITERAL_STRING("In shutdown") :
|
||||
NS_LITERAL_STRING("No stream."));
|
||||
mOnFailure->OnError(error);
|
||||
CallOnError(mOnFailure, *error);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
@ -1511,7 +1606,7 @@ public:
|
||||
// be invalidated from the main-thread (see OnNavigation)
|
||||
if (auto* window = nsGlobalWindowInner::GetInnerWindowWithId(windowID)) {
|
||||
auto streamError = MakeRefPtr<MediaStreamError>(window->AsInner(), *error);
|
||||
onFailure->OnError(streamError);
|
||||
CallOnError(onFailure, *streamError);
|
||||
}
|
||||
});
|
||||
|
||||
@ -1525,8 +1620,8 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
nsMainThreadPtrHandle<nsIDOMGetUserMediaSuccessCallback> mOnSuccess;
|
||||
nsMainThreadPtrHandle<nsIDOMGetUserMediaErrorCallback> mOnFailure;
|
||||
nsMainThreadPtrHandle<MediaManager::GetUserMediaSuccessCallback> mOnSuccess;
|
||||
nsMainThreadPtrHandle<MediaManager::GetUserMediaErrorCallback> mOnFailure;
|
||||
MediaStreamConstraints mConstraints;
|
||||
RefPtr<MediaDevice> mAudioDevice;
|
||||
RefPtr<MediaDevice> mVideoDevice;
|
||||
@ -1672,8 +1767,8 @@ class GetUserMediaTask : public Runnable
|
||||
public:
|
||||
GetUserMediaTask(
|
||||
const MediaStreamConstraints& aConstraints,
|
||||
const nsMainThreadPtrHandle<nsIDOMGetUserMediaSuccessCallback>& aOnSuccess,
|
||||
const nsMainThreadPtrHandle<nsIDOMGetUserMediaErrorCallback>& aOnFailure,
|
||||
const nsMainThreadPtrHandle<MediaManager::GetUserMediaSuccessCallback>& aOnSuccess,
|
||||
const nsMainThreadPtrHandle<MediaManager::GetUserMediaErrorCallback>& aOnFailure,
|
||||
uint64_t aWindowID,
|
||||
GetUserMediaWindowListener* aWindowListener,
|
||||
SourceListener* aSourceListener,
|
||||
@ -1822,7 +1917,7 @@ public:
|
||||
if (auto* window = nsGlobalWindowInner::GetInnerWindowWithId(mWindowID)) {
|
||||
RefPtr<MediaStreamError> error = new MediaStreamError(window->AsInner(),
|
||||
aName, aMessage);
|
||||
mOnFailure->OnError(error);
|
||||
CallOnError(mOnFailure, *error);
|
||||
}
|
||||
// Should happen *after* error runs for consistency, but may not matter
|
||||
mWindowListener->Remove(mSourceListener);
|
||||
@ -1872,8 +1967,8 @@ public:
|
||||
private:
|
||||
MediaStreamConstraints mConstraints;
|
||||
|
||||
nsMainThreadPtrHandle<nsIDOMGetUserMediaSuccessCallback> mOnSuccess;
|
||||
nsMainThreadPtrHandle<nsIDOMGetUserMediaErrorCallback> mOnFailure;
|
||||
nsMainThreadPtrHandle<MediaManager::GetUserMediaSuccessCallback> mOnSuccess;
|
||||
nsMainThreadPtrHandle<MediaManager::GetUserMediaErrorCallback> mOnFailure;
|
||||
uint64_t mWindowID;
|
||||
RefPtr<GetUserMediaWindowListener> mWindowListener;
|
||||
RefPtr<SourceListener> mSourceListener;
|
||||
@ -2497,20 +2592,20 @@ ReduceConstraint(
|
||||
nsresult
|
||||
MediaManager::GetUserMedia(nsPIDOMWindowInner* aWindow,
|
||||
const MediaStreamConstraints& aConstraintsPassedIn,
|
||||
nsIDOMGetUserMediaSuccessCallback* aOnSuccess,
|
||||
nsIDOMGetUserMediaErrorCallback* aOnFailure,
|
||||
GetUserMediaSuccessCallback&& aOnSuccess,
|
||||
GetUserMediaErrorCallback&& aOnFailure,
|
||||
dom::CallerType aCallerType)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aWindow);
|
||||
MOZ_ASSERT(aOnFailure);
|
||||
MOZ_ASSERT(aOnSuccess);
|
||||
nsMainThreadPtrHandle<nsIDOMGetUserMediaSuccessCallback> onSuccess(
|
||||
new nsMainThreadPtrHolder<nsIDOMGetUserMediaSuccessCallback>(
|
||||
"GetUserMedia::SuccessCallback", aOnSuccess));
|
||||
nsMainThreadPtrHandle<nsIDOMGetUserMediaErrorCallback> onFailure(
|
||||
new nsMainThreadPtrHolder<nsIDOMGetUserMediaErrorCallback>(
|
||||
"GetUserMedia::FailureCallback", aOnFailure));
|
||||
MOZ_ASSERT(aOnFailure.GetISupports());
|
||||
MOZ_ASSERT(aOnSuccess.GetISupports());
|
||||
nsMainThreadPtrHandle<GetUserMediaSuccessCallback> onSuccess(
|
||||
new nsMainThreadPtrHolder<GetUserMediaSuccessCallback>(
|
||||
"GetUserMedia::SuccessCallback", std::move(aOnSuccess)));
|
||||
nsMainThreadPtrHandle<GetUserMediaErrorCallback> onFailure(
|
||||
new nsMainThreadPtrHolder<GetUserMediaErrorCallback>(
|
||||
"GetUserMedia::FailureCallback", std::move(aOnFailure)));
|
||||
uint64_t windowID = aWindow->WindowID();
|
||||
|
||||
MediaStreamConstraints c(aConstraintsPassedIn); // use a modifiable copy
|
||||
@ -2523,14 +2618,14 @@ MediaManager::GetUserMedia(nsPIDOMWindowInner* aWindow,
|
||||
new MediaStreamError(aWindow,
|
||||
MediaStreamError::Name::TypeError,
|
||||
NS_LITERAL_STRING("audio and/or video is required"));
|
||||
onFailure->OnError(error);
|
||||
CallOnError(onFailure, *error);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!IsFullyActive(aWindow)) {
|
||||
RefPtr<MediaStreamError> error =
|
||||
new MediaStreamError(aWindow, MediaStreamError::Name::InvalidStateError);
|
||||
onFailure->OnError(error);
|
||||
CallOnError(onFailure, *error);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -2539,7 +2634,7 @@ MediaManager::GetUserMedia(nsPIDOMWindowInner* aWindow,
|
||||
new MediaStreamError(aWindow,
|
||||
MediaStreamError::Name::AbortError,
|
||||
NS_LITERAL_STRING("In shutdown"));
|
||||
onFailure->OnError(error);
|
||||
CallOnError(onFailure, *error);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -2652,7 +2747,7 @@ MediaManager::GetUserMedia(nsPIDOMWindowInner* aWindow,
|
||||
RefPtr<MediaStreamError> error =
|
||||
new MediaStreamError(aWindow,
|
||||
MediaStreamError::Name::NotAllowedError);
|
||||
onFailure->OnError(error);
|
||||
CallOnError(onFailure, *error);
|
||||
return NS_OK;
|
||||
}
|
||||
break;
|
||||
@ -2665,7 +2760,7 @@ MediaManager::GetUserMedia(nsPIDOMWindowInner* aWindow,
|
||||
MediaStreamError::Name::OverconstrainedError,
|
||||
NS_LITERAL_STRING(""),
|
||||
NS_LITERAL_STRING("mediaSource"));
|
||||
onFailure->OnError(error);
|
||||
CallOnError(onFailure, *error);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
@ -2732,7 +2827,7 @@ MediaManager::GetUserMedia(nsPIDOMWindowInner* aWindow,
|
||||
RefPtr<MediaStreamError> error =
|
||||
new MediaStreamError(aWindow,
|
||||
MediaStreamError::Name::NotAllowedError);
|
||||
onFailure->OnError(error);
|
||||
CallOnError(onFailure, *error);
|
||||
return NS_OK;
|
||||
}
|
||||
break;
|
||||
@ -2744,7 +2839,7 @@ MediaManager::GetUserMedia(nsPIDOMWindowInner* aWindow,
|
||||
MediaStreamError::Name::OverconstrainedError,
|
||||
NS_LITERAL_STRING(""),
|
||||
NS_LITERAL_STRING("mediaSource"));
|
||||
onFailure->OnError(error);
|
||||
CallOnError(onFailure, *error);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
@ -2815,7 +2910,7 @@ MediaManager::GetUserMedia(nsPIDOMWindowInner* aWindow,
|
||||
(IsOn(c.mVideo) && videoPerm == nsIPermissionManager::DENY_ACTION)) {
|
||||
RefPtr<MediaStreamError> error =
|
||||
new MediaStreamError(aWindow, MediaStreamError::Name::NotAllowedError);
|
||||
onFailure->OnError(error);
|
||||
CallOnError(onFailure, *error);
|
||||
windowListener->Remove(sourceListener);
|
||||
return NS_OK;
|
||||
}
|
||||
@ -2925,7 +3020,7 @@ MediaManager::GetUserMedia(nsPIDOMWindowInner* aWindow,
|
||||
MediaStreamError::Name::OverconstrainedError,
|
||||
NS_LITERAL_STRING(""),
|
||||
constraint);
|
||||
onFailure->OnError(error);
|
||||
CallOnError(onFailure, *error);
|
||||
return;
|
||||
}
|
||||
if (!(*devices)->Length()) {
|
||||
@ -2939,7 +3034,7 @@ MediaManager::GetUserMedia(nsPIDOMWindowInner* aWindow,
|
||||
// device, so report NotAllowedError.
|
||||
resistFingerprinting ? MediaStreamError::Name::NotAllowedError
|
||||
: MediaStreamError::Name::NotFoundError);
|
||||
onFailure->OnError(error);
|
||||
CallOnError(onFailure, *error);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -3000,11 +3095,11 @@ MediaManager::GetUserMedia(nsPIDOMWindowInner* aWindow,
|
||||
#endif
|
||||
}, [onFailure](MediaStreamError*& reason) mutable {
|
||||
LOG(("GetUserMedia: post enumeration pledge2 failure callback called!"));
|
||||
onFailure->OnError(reason);
|
||||
CallOnError(onFailure, *reason);
|
||||
});
|
||||
}, [onFailure](MediaStreamError*& reason) mutable {
|
||||
LOG(("GetUserMedia: post enumeration pledge failure callback called!"));
|
||||
onFailure->OnError(reason);
|
||||
CallOnError(onFailure, *reason);
|
||||
});
|
||||
return NS_OK;
|
||||
}
|
||||
@ -3293,14 +3388,11 @@ MediaManager::EnumerateDevices(nsPIDOMWindowInner* aWindow,
|
||||
nsresult
|
||||
MediaManager::GetUserMediaDevices(nsPIDOMWindowInner* aWindow,
|
||||
const MediaStreamConstraints& aConstraints,
|
||||
nsIGetUserMediaDevicesSuccessCallback* aOnSuccess,
|
||||
nsIDOMGetUserMediaErrorCallback* aOnFailure,
|
||||
dom::MozGetUserMediaDevicesSuccessCallback& aOnSuccess,
|
||||
uint64_t aWindowId,
|
||||
const nsAString& aCallID)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
nsCOMPtr<nsIGetUserMediaDevicesSuccessCallback> onSuccess(aOnSuccess);
|
||||
nsCOMPtr<nsIDOMGetUserMediaErrorCallback> onFailure(aOnFailure);
|
||||
if (!aWindowId) {
|
||||
aWindowId = aWindow->WindowID();
|
||||
}
|
||||
@ -3317,7 +3409,7 @@ MediaManager::GetUserMediaDevices(nsPIDOMWindowInner* aWindow,
|
||||
if (!aCallID.Length() || aCallID == callID) {
|
||||
if (mActiveCallbacks.Get(callID, getter_AddRefs(task))) {
|
||||
nsCOMPtr<nsIWritableVariant> array = MediaManager_ToJSArray(*task->mMediaDeviceSet);
|
||||
onSuccess->OnSuccess(array);
|
||||
aOnSuccess.Call(array);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "mozilla/dom/MediaStreamBinding.h"
|
||||
#include "mozilla/dom/MediaStreamTrackBinding.h"
|
||||
#include "mozilla/dom/MediaStreamError.h"
|
||||
#include "mozilla/dom/NavigatorBinding.h"
|
||||
#include "mozilla/media/MediaChild.h"
|
||||
#include "mozilla/media/MediaParent.h"
|
||||
#include "mozilla/Logging.h"
|
||||
@ -202,17 +203,21 @@ public:
|
||||
void RemoveFromWindowList(uint64_t aWindowID,
|
||||
GetUserMediaWindowListener *aListener);
|
||||
|
||||
typedef dom::CallbackObjectHolder<dom::NavigatorUserMediaSuccessCallback,
|
||||
nsIDOMGetUserMediaSuccessCallback> GetUserMediaSuccessCallback;
|
||||
typedef dom::CallbackObjectHolder<dom::NavigatorUserMediaErrorCallback,
|
||||
nsIDOMGetUserMediaErrorCallback> GetUserMediaErrorCallback;
|
||||
|
||||
nsresult GetUserMedia(
|
||||
nsPIDOMWindowInner* aWindow,
|
||||
const dom::MediaStreamConstraints& aConstraints,
|
||||
nsIDOMGetUserMediaSuccessCallback* onSuccess,
|
||||
nsIDOMGetUserMediaErrorCallback* onError,
|
||||
GetUserMediaSuccessCallback&& onSuccess,
|
||||
GetUserMediaErrorCallback&& onError,
|
||||
dom::CallerType aCallerType);
|
||||
|
||||
nsresult GetUserMediaDevices(nsPIDOMWindowInner* aWindow,
|
||||
const dom::MediaStreamConstraints& aConstraints,
|
||||
nsIGetUserMediaDevicesSuccessCallback* onSuccess,
|
||||
nsIDOMGetUserMediaErrorCallback* onError,
|
||||
dom::MozGetUserMediaDevicesSuccessCallback& aOnSuccess,
|
||||
uint64_t aInnerWindowID = 0,
|
||||
const nsAString& aCallID = nsString());
|
||||
|
||||
|
@ -755,10 +755,14 @@ SpeechRecognition::Start(const Optional<NonNull<DOMMediaStream>>& aStream,
|
||||
} else {
|
||||
AutoNoJSAPI();
|
||||
MediaManager* manager = MediaManager::Get();
|
||||
MediaManager::GetUserMediaSuccessCallback onsuccess(
|
||||
new GetUserMediaSuccessCallback(this));
|
||||
MediaManager::GetUserMediaErrorCallback onerror(
|
||||
new GetUserMediaErrorCallback(this));
|
||||
manager->GetUserMedia(GetOwner(),
|
||||
constraints,
|
||||
new GetUserMediaSuccessCallback(this),
|
||||
new GetUserMediaErrorCallback(this),
|
||||
std::move(onsuccess),
|
||||
std::move(onerror),
|
||||
aCallerType);
|
||||
}
|
||||
|
||||
|
@ -61,6 +61,11 @@ interface AccessibleNode {
|
||||
attribute DOMString? live;
|
||||
attribute DOMString? relevant;
|
||||
|
||||
// Other relationships
|
||||
attribute AccessibleNode? activeDescendant;
|
||||
attribute AccessibleNode? details;
|
||||
attribute AccessibleNode? errorMessage;
|
||||
|
||||
// Collections.
|
||||
attribute long? colCount;
|
||||
attribute unsigned long? colIndex;
|
||||
|
@ -513,7 +513,7 @@ public:
|
||||
// contents start at rightside also cause their horizontal scrollbars, if any,
|
||||
// initially start at rightside. So we can also learn about the initial side
|
||||
// of the horizontal scrollbar for the frame by calling this function.
|
||||
bool IsHorizontalContentRightToLeft() {
|
||||
bool IsHorizontalContentRightToLeft() const {
|
||||
return mScrollableRect.x < 0;
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "Units.h" // for ParentLayerIntRect
|
||||
#include "gfxRect.h" // for gfxRect
|
||||
#include "gfxUtils.h" // for gfxUtils
|
||||
#include "mozilla/ArrayUtils.h" // for ArrayEqual
|
||||
#include "mozilla/gfx/BaseSize.h" // for BaseSize
|
||||
#include "mozilla/gfx/Point.h" // for IntSize
|
||||
#include "mozilla/mozalloc.h" // for operator new, etc
|
||||
|
@ -821,7 +821,6 @@ AsyncPanZoomController::AsyncPanZoomController(LayersId aLayersId,
|
||||
mRefPtrMonitor("RefPtrMonitor"),
|
||||
// mTreeManager must be initialized before GetFrameTime() is called
|
||||
mTreeManager(aTreeManager),
|
||||
mFrameMetrics(mScrollMetadata.GetMetrics()),
|
||||
mRecursiveMutex("AsyncPanZoomController"),
|
||||
mLastContentPaintMetrics(mLastContentPaintMetadata.GetMetrics()),
|
||||
mX(this),
|
||||
@ -829,8 +828,8 @@ AsyncPanZoomController::AsyncPanZoomController(LayersId aLayersId,
|
||||
mPanDirRestricted(false),
|
||||
mPinchLocked(false),
|
||||
mZoomConstraints(false, false,
|
||||
mFrameMetrics.GetDevPixelsPerCSSPixel() * kViewportMinScale / ParentLayerToScreenScale(1),
|
||||
mFrameMetrics.GetDevPixelsPerCSSPixel() * kViewportMaxScale / ParentLayerToScreenScale(1)),
|
||||
Metrics().GetDevPixelsPerCSSPixel() * kViewportMinScale / ParentLayerToScreenScale(1),
|
||||
Metrics().GetDevPixelsPerCSSPixel() * kViewportMaxScale / ParentLayerToScreenScale(1)),
|
||||
mLastSampleTime(GetFrameTime()),
|
||||
mLastCheckerboardReport(GetFrameTime()),
|
||||
mOverscrollEffect(MakeUnique<OverscrollEffect>(*this)),
|
||||
@ -899,7 +898,7 @@ AsyncPanZoomController::Destroy()
|
||||
|
||||
// Only send the release message if the SharedFrameMetrics has been created.
|
||||
if (mMetricsSharingController && mSharedFrameMetricsBuffer) {
|
||||
Unused << mMetricsSharingController->StopSharingMetrics(mFrameMetrics.GetScrollId(), mAPZCId);
|
||||
Unused << mMetricsSharingController->StopSharingMetrics(Metrics().GetScrollId(), mAPZCId);
|
||||
}
|
||||
|
||||
{ // scope the lock
|
||||
@ -1063,16 +1062,16 @@ nsEventStatus AsyncPanZoomController::HandleDragEvent(const MouseInput& aEvent,
|
||||
APZC_LOG("%p scrollbar dragged to %f percent\n", this, scrollPercent);
|
||||
|
||||
CSSCoord minScrollPosition =
|
||||
GetAxisStart(direction, mFrameMetrics.GetScrollableRect().TopLeft());
|
||||
GetAxisStart(direction, Metrics().GetScrollableRect().TopLeft());
|
||||
CSSCoord maxScrollPosition =
|
||||
GetAxisStart(direction, mFrameMetrics.GetScrollableRect().BottomRight()) -
|
||||
GetAxisLength(direction, mFrameMetrics.CalculateCompositionBoundsInCssPixelsOfSurroundingContent());
|
||||
GetAxisStart(direction, Metrics().GetScrollableRect().BottomRight()) -
|
||||
GetAxisLength(direction, Metrics().CalculateCompositionBoundsInCssPixelsOfSurroundingContent());
|
||||
CSSCoord scrollPosition = minScrollPosition + (scrollPercent * (maxScrollPosition - minScrollPosition));
|
||||
|
||||
scrollPosition = std::max(scrollPosition, minScrollPosition);
|
||||
scrollPosition = std::min(scrollPosition, maxScrollPosition);
|
||||
|
||||
CSSPoint scrollOffset = mFrameMetrics.GetScrollOffset();
|
||||
CSSPoint scrollOffset = Metrics().GetScrollOffset();
|
||||
if (direction == ScrollDirection::eHorizontal) {
|
||||
scrollOffset.x = scrollPosition;
|
||||
} else {
|
||||
@ -1463,7 +1462,7 @@ nsEventStatus AsyncPanZoomController::OnScaleBegin(const PinchGestureInput& aEve
|
||||
SetState(PINCHING);
|
||||
mX.SetVelocity(0);
|
||||
mY.SetVelocity(0);
|
||||
mLastZoomFocus = aEvent.mLocalFocusPoint - mFrameMetrics.GetCompositionBounds().TopLeft();
|
||||
mLastZoomFocus = aEvent.mLocalFocusPoint - Metrics().GetCompositionBounds().TopLeft();
|
||||
|
||||
return nsEventStatus_eConsumeNoDefault;
|
||||
}
|
||||
@ -1484,7 +1483,7 @@ nsEventStatus AsyncPanZoomController::OnScale(const PinchGestureInput& aEvent) {
|
||||
{
|
||||
RecursiveMutexAutoLock lock(mRecursiveMutex);
|
||||
|
||||
focusPoint = aEvent.mLocalFocusPoint - mFrameMetrics.GetCompositionBounds().TopLeft();
|
||||
focusPoint = aEvent.mLocalFocusPoint - Metrics().GetCompositionBounds().TopLeft();
|
||||
focusChange = mLastZoomFocus - focusPoint;
|
||||
mLastZoomFocus = focusPoint;
|
||||
}
|
||||
@ -1517,14 +1516,14 @@ nsEventStatus AsyncPanZoomController::OnScale(const PinchGestureInput& aEvent) {
|
||||
// would have to be adjusted (as e.g. it would no longer be valid to take
|
||||
// the minimum or maximum of the ratios of the widths and heights of the
|
||||
// page rect and the composition bounds).
|
||||
MOZ_ASSERT(mFrameMetrics.IsRootContent());
|
||||
MOZ_ASSERT(mFrameMetrics.GetZoom().AreScalesSame());
|
||||
MOZ_ASSERT(Metrics().IsRootContent());
|
||||
MOZ_ASSERT(Metrics().GetZoom().AreScalesSame());
|
||||
|
||||
{
|
||||
RecursiveMutexAutoLock lock(mRecursiveMutex);
|
||||
|
||||
CSSToParentLayerScale userZoom = mFrameMetrics.GetZoom().ToScaleFactor();
|
||||
CSSPoint cssFocusPoint = focusPoint / mFrameMetrics.GetZoom();
|
||||
CSSToParentLayerScale userZoom = Metrics().GetZoom().ToScaleFactor();
|
||||
CSSPoint cssFocusPoint = focusPoint / Metrics().GetZoom();
|
||||
|
||||
// If displacing by the change in focus point will take us off page bounds,
|
||||
// then reduce the displacement such that it doesn't.
|
||||
@ -1556,9 +1555,9 @@ nsEventStatus AsyncPanZoomController::OnScale(const PinchGestureInput& aEvent) {
|
||||
CSSToParentLayerScale realMinZoom = mZoomConstraints.mMinZoom;
|
||||
CSSToParentLayerScale realMaxZoom = mZoomConstraints.mMaxZoom;
|
||||
realMinZoom.scale = std::max(realMinZoom.scale,
|
||||
mFrameMetrics.GetCompositionBounds().Width() / mFrameMetrics.GetScrollableRect().Width());
|
||||
Metrics().GetCompositionBounds().Width() / Metrics().GetScrollableRect().Width());
|
||||
realMinZoom.scale = std::max(realMinZoom.scale,
|
||||
mFrameMetrics.GetCompositionBounds().Height() / mFrameMetrics.GetScrollableRect().Height());
|
||||
Metrics().GetCompositionBounds().Height() / Metrics().GetScrollableRect().Height());
|
||||
if (realMaxZoom < realMinZoom) {
|
||||
realMaxZoom = realMinZoom;
|
||||
}
|
||||
@ -1763,13 +1762,13 @@ AsyncPanZoomController::ConvertScrollbarPoint(const ParentLayerPoint& aScrollbar
|
||||
RecursiveMutexAutoLock lock(mRecursiveMutex);
|
||||
|
||||
// First, get it into the right coordinate space.
|
||||
CSSPoint scrollbarPoint = aScrollbarPoint / mFrameMetrics.GetZoom();
|
||||
CSSPoint scrollbarPoint = aScrollbarPoint / Metrics().GetZoom();
|
||||
// The scrollbar can be transformed with the frame but the pres shell
|
||||
// resolution is only applied to the scroll frame.
|
||||
scrollbarPoint = scrollbarPoint * mFrameMetrics.GetPresShellResolution();
|
||||
scrollbarPoint = scrollbarPoint * Metrics().GetPresShellResolution();
|
||||
|
||||
// Now, get it to be relative to the beginning of the scroll track.
|
||||
CSSRect cssCompositionBound = mFrameMetrics.CalculateCompositionBoundsInCssPixelsOfSurroundingContent();
|
||||
CSSRect cssCompositionBound = Metrics().CalculateCompositionBoundsInCssPixelsOfSurroundingContent();
|
||||
return GetAxisStart(*aThumbData.mDirection, scrollbarPoint)
|
||||
- GetAxisStart(*aThumbData.mDirection, cssCompositionBound)
|
||||
- aThumbData.mScrollTrackStart;
|
||||
@ -1808,9 +1807,9 @@ AsyncPanZoomController::GetScrollWheelDelta(const ScrollWheelInput& aEvent,
|
||||
LayoutDeviceIntSize scrollAmountLD = mScrollMetadata.GetLineScrollAmount();
|
||||
LayoutDeviceIntSize pageScrollSizeLD = mScrollMetadata.GetPageScrollAmount();
|
||||
scrollAmount = scrollAmountLD /
|
||||
mFrameMetrics.GetDevPixelsPerCSSPixel() * mFrameMetrics.GetZoom();
|
||||
Metrics().GetDevPixelsPerCSSPixel() * Metrics().GetZoom();
|
||||
pageScrollSize = pageScrollSizeLD /
|
||||
mFrameMetrics.GetDevPixelsPerCSSPixel() * mFrameMetrics.GetZoom();
|
||||
Metrics().GetDevPixelsPerCSSPixel() * Metrics().GetZoom();
|
||||
}
|
||||
|
||||
ParentLayerPoint delta;
|
||||
@ -1897,8 +1896,8 @@ AsyncPanZoomController::OnKeyboard(const KeyboardInput& aEvent)
|
||||
|
||||
// CallDispatchScroll interprets the start and end points as the start and
|
||||
// end of a touch scroll so they need to be reversed.
|
||||
ParentLayerPoint startPoint = destination * mFrameMetrics.GetZoom();
|
||||
ParentLayerPoint endPoint = mFrameMetrics.GetScrollOffset() * mFrameMetrics.GetZoom();
|
||||
ParentLayerPoint startPoint = destination * Metrics().GetZoom();
|
||||
ParentLayerPoint endPoint = Metrics().GetScrollOffset() * Metrics().GetZoom();
|
||||
ParentLayerPoint delta = endPoint - startPoint;
|
||||
|
||||
ScreenPoint distance = ToScreenCoordinates(
|
||||
@ -1935,7 +1934,7 @@ AsyncPanZoomController::OnKeyboard(const KeyboardInput& aEvent)
|
||||
CancelAnimation();
|
||||
SetState(KEYBOARD_SCROLL);
|
||||
|
||||
nsPoint initialPosition = CSSPoint::ToAppUnits(mFrameMetrics.GetScrollOffset());
|
||||
nsPoint initialPosition = CSSPoint::ToAppUnits(Metrics().GetScrollOffset());
|
||||
StartAnimation(new KeyboardScrollAnimation(*this, initialPosition, aEvent.mAction.mType));
|
||||
}
|
||||
|
||||
@ -1944,7 +1943,7 @@ AsyncPanZoomController::OnKeyboard(const KeyboardInput& aEvent)
|
||||
nsPoint velocity =
|
||||
CSSPoint::ToAppUnits(
|
||||
ParentLayerPoint(mX.GetVelocity() * 1000.0f, mY.GetVelocity() * 1000.0f) /
|
||||
mFrameMetrics.GetZoom());
|
||||
Metrics().GetZoom());
|
||||
|
||||
KeyboardScrollAnimation* animation = mAnimation->AsKeyboardScrollAnimation();
|
||||
MOZ_ASSERT(animation);
|
||||
@ -1969,9 +1968,9 @@ AsyncPanZoomController::GetKeyboardDestination(const KeyboardScrollAction& aActi
|
||||
RecursiveMutexAutoLock lock(mRecursiveMutex);
|
||||
|
||||
lineScrollSize = mScrollMetadata.GetLineScrollAmount() /
|
||||
mFrameMetrics.GetDevPixelsPerCSSPixel();
|
||||
Metrics().GetDevPixelsPerCSSPixel();
|
||||
pageScrollSize = mScrollMetadata.GetPageScrollAmount() /
|
||||
mFrameMetrics.GetDevPixelsPerCSSPixel();
|
||||
Metrics().GetDevPixelsPerCSSPixel();
|
||||
|
||||
if (mState == WHEEL_SCROLL) {
|
||||
scrollOffset = mAnimation->AsWheelScrollAnimation()->GetDestination();
|
||||
@ -1980,10 +1979,10 @@ AsyncPanZoomController::GetKeyboardDestination(const KeyboardScrollAction& aActi
|
||||
} else if (mState == KEYBOARD_SCROLL) {
|
||||
scrollOffset = mAnimation->AsKeyboardScrollAnimation()->GetDestination();
|
||||
} else {
|
||||
scrollOffset = mFrameMetrics.GetScrollOffset();
|
||||
scrollOffset = Metrics().GetScrollOffset();
|
||||
}
|
||||
|
||||
scrollRect = mFrameMetrics.GetScrollableRect();
|
||||
scrollRect = Metrics().GetScrollableRect();
|
||||
}
|
||||
|
||||
// Calculate the scroll destination based off of the scroll type and direction
|
||||
@ -2140,7 +2139,7 @@ AsyncPanZoomController::IsContentOfHonouredTargetRightToLeft(
|
||||
return mScrollMetadata.IsAutoDirRootContentRTL();
|
||||
}
|
||||
RecursiveMutexAutoLock lock(mRecursiveMutex);
|
||||
return mFrameMetrics.IsHorizontalContentRightToLeft();
|
||||
return Metrics().IsHorizontalContentRightToLeft();
|
||||
}
|
||||
|
||||
bool
|
||||
@ -2237,7 +2236,7 @@ nsEventStatus AsyncPanZoomController::OnScrollWheel(const ScrollWheelInput& aEve
|
||||
gfxPrefs::MouseScrollTestingEnabled()) {
|
||||
if (RefPtr<GeckoContentController> controller = GetGeckoContentController()) {
|
||||
controller->NotifyMozMouseScrollEvent(
|
||||
mFrameMetrics.GetScrollId(),
|
||||
Metrics().GetScrollId(),
|
||||
NS_LITERAL_STRING("MozMouseScrollFailed"));
|
||||
}
|
||||
}
|
||||
@ -2259,7 +2258,7 @@ nsEventStatus AsyncPanZoomController::OnScrollWheel(const ScrollWheelInput& aEve
|
||||
// Wheel events from "clicky" mouse wheels trigger scroll snapping to the
|
||||
// next snap point. Check for this, and adjust the delta to take into
|
||||
// account the snap point.
|
||||
CSSPoint startPosition = mFrameMetrics.GetScrollOffset();
|
||||
CSSPoint startPosition = Metrics().GetScrollOffset();
|
||||
MaybeAdjustDeltaForScrollSnapping(aEvent, delta, startPosition);
|
||||
|
||||
ScreenPoint distance = ToScreenCoordinates(
|
||||
@ -2292,7 +2291,7 @@ nsEventStatus AsyncPanZoomController::OnScrollWheel(const ScrollWheelInput& aEve
|
||||
RecursiveMutexAutoLock lock(mRecursiveMutex);
|
||||
|
||||
// Perform scroll snapping if appropriate.
|
||||
CSSPoint startPosition = mFrameMetrics.GetScrollOffset();
|
||||
CSSPoint startPosition = Metrics().GetScrollOffset();
|
||||
// If we're already in a wheel scroll or smooth scroll animation,
|
||||
// the delta is applied to its destination, not to the current
|
||||
// scroll position. Take this into account when finding a snap point.
|
||||
@ -2317,13 +2316,13 @@ nsEventStatus AsyncPanZoomController::OnScrollWheel(const ScrollWheelInput& aEve
|
||||
CancelAnimation();
|
||||
SetState(WHEEL_SCROLL);
|
||||
|
||||
nsPoint initialPosition = CSSPoint::ToAppUnits(mFrameMetrics.GetScrollOffset());
|
||||
nsPoint initialPosition = CSSPoint::ToAppUnits(Metrics().GetScrollOffset());
|
||||
StartAnimation(new WheelScrollAnimation(
|
||||
*this, initialPosition, aEvent.mDeltaType));
|
||||
}
|
||||
|
||||
nsPoint deltaInAppUnits =
|
||||
CSSPoint::ToAppUnits(delta / mFrameMetrics.GetZoom());
|
||||
CSSPoint::ToAppUnits(delta / Metrics().GetZoom());
|
||||
|
||||
// Convert velocity from ParentLayerPoints/ms to ParentLayerPoints/s and
|
||||
// then to appunits/second.
|
||||
@ -2331,7 +2330,7 @@ nsEventStatus AsyncPanZoomController::OnScrollWheel(const ScrollWheelInput& aEve
|
||||
CSSPoint::ToAppUnits(
|
||||
ParentLayerPoint(mX.GetVelocity() * 1000.0f,
|
||||
mY.GetVelocity() * 1000.0f) /
|
||||
mFrameMetrics.GetZoom());
|
||||
Metrics().GetZoom());
|
||||
|
||||
WheelScrollAnimation* animation = mAnimation->AsWheelScrollAnimation();
|
||||
animation->UpdateDelta(aEvent.mTimeStamp, deltaInAppUnits, nsSize(velocity.x, velocity.y));
|
||||
@ -2350,7 +2349,7 @@ AsyncPanZoomController::NotifyMozMouseScrollEvent(const nsString& aString) const
|
||||
return;
|
||||
}
|
||||
|
||||
controller->NotifyMozMouseScrollEvent(mFrameMetrics.GetScrollId(), aString);
|
||||
controller->NotifyMozMouseScrollEvent(Metrics().GetScrollId(), aString);
|
||||
}
|
||||
|
||||
nsEventStatus AsyncPanZoomController::OnPanMayBegin(const PanGestureInput& aEvent) {
|
||||
@ -2935,7 +2934,7 @@ bool AsyncPanZoomController::AttemptScroll(ParentLayerPoint& aStartPoint,
|
||||
}
|
||||
|
||||
if (!IsZero(adjustedDisplacement)) {
|
||||
ScrollBy(adjustedDisplacement / mFrameMetrics.GetZoom());
|
||||
ScrollBy(adjustedDisplacement / Metrics().GetZoom());
|
||||
if (InputBlockState* block = GetCurrentInputBlock()) {
|
||||
#if defined(MOZ_WIDGET_ANDROID)
|
||||
if (block->AsTouchBlock() && (block->GetScrolledApzc() != this) && IsRootContent()) {
|
||||
@ -3155,14 +3154,14 @@ void AsyncPanZoomController::SmoothScrollTo(const CSSPoint& aDestination) {
|
||||
} else {
|
||||
CancelAnimation();
|
||||
SetState(SMOOTH_SCROLL);
|
||||
nsPoint initialPosition = CSSPoint::ToAppUnits(mFrameMetrics.GetScrollOffset());
|
||||
nsPoint initialPosition = CSSPoint::ToAppUnits(Metrics().GetScrollOffset());
|
||||
// Convert velocity from ParentLayerPoints/ms to ParentLayerPoints/s and
|
||||
// then to appunits/second.
|
||||
nsPoint initialVelocity =
|
||||
CSSPoint::ToAppUnits(
|
||||
ParentLayerPoint(mX.GetVelocity() * 1000.0f,
|
||||
mY.GetVelocity() * 1000.0f) /
|
||||
mFrameMetrics.GetZoom());
|
||||
Metrics().GetZoom());
|
||||
|
||||
nsPoint destination = CSSPoint::ToAppUnits(aDestination);
|
||||
|
||||
@ -3309,13 +3308,13 @@ void AsyncPanZoomController::AdjustScrollForSurfaceShift(const ScreenPoint& aShi
|
||||
RecursiveMutexAutoLock lock(mRecursiveMutex);
|
||||
CSSPoint adjustment =
|
||||
ViewAs<ParentLayerPixel>(aShift, PixelCastJustification::ScreenIsParentLayerForRoot)
|
||||
/ mFrameMetrics.GetZoom();
|
||||
/ Metrics().GetZoom();
|
||||
APZC_LOG("%p adjusting scroll position by %s for surface shift\n",
|
||||
this, Stringify(adjustment).c_str());
|
||||
CSSRect scrollRange = mFrameMetrics.CalculateScrollRange();
|
||||
// Apply shift to mFrameMetrics.mScrollOffset.
|
||||
CSSRect scrollRange = Metrics().CalculateScrollRange();
|
||||
// Apply shift to Metrics().mScrollOffset.
|
||||
SetScrollOffset(scrollRange.ClampPoint(
|
||||
mFrameMetrics.GetScrollOffset() + adjustment));
|
||||
Metrics().GetScrollOffset() + adjustment));
|
||||
// Apply shift to mCompositedScrollOffset, since the dynamic toolbar expects
|
||||
// the shift to take effect right away, without the usual frame delay.
|
||||
mCompositedScrollOffset = scrollRange.ClampPoint(
|
||||
@ -3325,36 +3324,36 @@ void AsyncPanZoomController::AdjustScrollForSurfaceShift(const ScreenPoint& aShi
|
||||
}
|
||||
|
||||
void AsyncPanZoomController::SetScrollOffset(const CSSPoint& aOffset) {
|
||||
mFrameMetrics.SetScrollOffset(aOffset);
|
||||
mFrameMetrics.RecalculateViewportOffset();
|
||||
Metrics().SetScrollOffset(aOffset);
|
||||
Metrics().RecalculateViewportOffset();
|
||||
}
|
||||
|
||||
void AsyncPanZoomController::ClampAndSetScrollOffset(const CSSPoint& aOffset) {
|
||||
mFrameMetrics.ClampAndSetScrollOffset(aOffset);
|
||||
mFrameMetrics.RecalculateViewportOffset();
|
||||
Metrics().ClampAndSetScrollOffset(aOffset);
|
||||
Metrics().RecalculateViewportOffset();
|
||||
}
|
||||
|
||||
void AsyncPanZoomController::ScrollBy(const CSSPoint& aOffset) {
|
||||
SetScrollOffset(mFrameMetrics.GetScrollOffset() + aOffset);
|
||||
SetScrollOffset(Metrics().GetScrollOffset() + aOffset);
|
||||
}
|
||||
|
||||
void AsyncPanZoomController::ScrollByAndClamp(const CSSPoint& aOffset) {
|
||||
ClampAndSetScrollOffset(mFrameMetrics.GetScrollOffset() + aOffset);
|
||||
ClampAndSetScrollOffset(Metrics().GetScrollOffset() + aOffset);
|
||||
}
|
||||
|
||||
void AsyncPanZoomController::CopyScrollInfoFrom(const FrameMetrics& aFrameMetrics) {
|
||||
mFrameMetrics.CopyScrollInfoFrom(aFrameMetrics);
|
||||
mFrameMetrics.RecalculateViewportOffset();
|
||||
Metrics().CopyScrollInfoFrom(aFrameMetrics);
|
||||
Metrics().RecalculateViewportOffset();
|
||||
}
|
||||
|
||||
void AsyncPanZoomController::ScaleWithFocus(float aScale,
|
||||
const CSSPoint& aFocus) {
|
||||
mFrameMetrics.ZoomBy(aScale);
|
||||
Metrics().ZoomBy(aScale);
|
||||
// We want to adjust the scroll offset such that the CSS point represented by aFocus remains
|
||||
// at the same position on the screen before and after the change in zoom. The below code
|
||||
// accomplishes this; see https://bugzilla.mozilla.org/show_bug.cgi?id=923431#c6 for an
|
||||
// in-depth explanation of how.
|
||||
SetScrollOffset((mFrameMetrics.GetScrollOffset() + aFocus) - (aFocus / aScale));
|
||||
SetScrollOffset((Metrics().GetScrollOffset() + aFocus) - (aFocus / aScale));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -3549,7 +3548,7 @@ bool AsyncPanZoomController::IsPannable() const {
|
||||
|
||||
bool AsyncPanZoomController::IsScrollInfoLayer() const {
|
||||
RecursiveMutexAutoLock lock(mRecursiveMutex);
|
||||
return mFrameMetrics.IsScrollInfoLayer();
|
||||
return Metrics().IsScrollInfoLayer();
|
||||
}
|
||||
|
||||
int32_t AsyncPanZoomController::GetLastTouchIdentifier() const {
|
||||
@ -3561,7 +3560,7 @@ void AsyncPanZoomController::RequestContentRepaint(bool aUserAction) {
|
||||
// Reinvoke this method on the repaint thread if it's not there already. It's
|
||||
// important to do this before the call to CalculatePendingDisplayPort, so
|
||||
// that CalculatePendingDisplayPort uses the most recent available version of
|
||||
// mFrameMetrics, just before the paint request is dispatched to content.
|
||||
// Metrics(). just before the paint request is dispatched to content.
|
||||
RefPtr<GeckoContentController> controller = GetGeckoContentController();
|
||||
if (!controller) {
|
||||
return;
|
||||
@ -3582,11 +3581,11 @@ void AsyncPanZoomController::RequestContentRepaint(bool aUserAction) {
|
||||
|
||||
RecursiveMutexAutoLock lock(mRecursiveMutex);
|
||||
ParentLayerPoint velocity = GetVelocityVector();
|
||||
mFrameMetrics.SetDisplayPortMargins(CalculatePendingDisplayPort(mFrameMetrics, velocity));
|
||||
mFrameMetrics.SetUseDisplayPortMargins(true);
|
||||
mFrameMetrics.SetPaintRequestTime(TimeStamp::Now());
|
||||
mFrameMetrics.SetRepaintDrivenByUserAction(aUserAction);
|
||||
RequestContentRepaint(mFrameMetrics, velocity);
|
||||
Metrics().SetDisplayPortMargins(CalculatePendingDisplayPort(Metrics(), velocity));
|
||||
Metrics().SetUseDisplayPortMargins(true);
|
||||
Metrics().SetPaintRequestTime(TimeStamp::Now());
|
||||
Metrics().SetRepaintDrivenByUserAction(aUserAction);
|
||||
RequestContentRepaint(Metrics(), velocity);
|
||||
}
|
||||
|
||||
/*static*/ CSSRect
|
||||
@ -3683,7 +3682,7 @@ bool AsyncPanZoomController::UpdateAnimation(const TimeStamp& aSampleTime,
|
||||
mLastSampleTime = aSampleTime;
|
||||
|
||||
if (mAnimation) {
|
||||
bool continueAnimation = mAnimation->Sample(mFrameMetrics, sampleTimeDelta);
|
||||
bool continueAnimation = mAnimation->Sample(Metrics(), sampleTimeDelta);
|
||||
bool wantsRepaints = mAnimation->WantsRepaints();
|
||||
*aOutDeferredTasks = mAnimation->TakeDeferredTasks();
|
||||
if (!continueAnimation) {
|
||||
@ -3749,8 +3748,8 @@ bool AsyncPanZoomController::AdvanceAnimations(const TimeStamp& aSampleTime)
|
||||
if (mCheckerboardEvent) {
|
||||
mCheckerboardEvent->UpdateRendertraceProperty(
|
||||
CheckerboardEvent::UserVisible,
|
||||
CSSRect(mFrameMetrics.GetScrollOffset(),
|
||||
mFrameMetrics.CalculateCompositedSizeInCssPixels()));
|
||||
CSSRect(Metrics().GetScrollOffset(),
|
||||
Metrics().CalculateCompositedSizeInCssPixels()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3771,7 +3770,7 @@ bool AsyncPanZoomController::AdvanceAnimations(const TimeStamp& aSampleTime)
|
||||
CSSRect
|
||||
AsyncPanZoomController::GetCurrentAsyncLayoutViewport(AsyncTransformConsumer aMode) const {
|
||||
RecursiveMutexAutoLock lock(mRecursiveMutex);
|
||||
MOZ_ASSERT(mFrameMetrics.IsRootContent(),
|
||||
MOZ_ASSERT(Metrics().IsRootContent(),
|
||||
"Only the root content APZC has a layout viewport");
|
||||
if (aMode == eForCompositing && mScrollMetadata.IsApzForceDisabled()) {
|
||||
return mLastContentPaintMetrics.GetViewport();
|
||||
@ -3844,7 +3843,7 @@ AsyncPanZoomController::GetCurrentAsyncTransform(AsyncTransformConsumer aMode) c
|
||||
* effectiveZoom * mTestAsyncZoom.scale;
|
||||
|
||||
LayerToParentLayerScale compositedAsyncZoom =
|
||||
(effectiveZoom / mFrameMetrics.LayersPixelsPerCSSPixel()).ToScaleFactor();
|
||||
(effectiveZoom / Metrics().LayersPixelsPerCSSPixel()).ToScaleFactor();
|
||||
return AsyncTransform(
|
||||
LayerToParentLayerScale(compositedAsyncZoom.scale * mTestAsyncZoom.scale),
|
||||
-translation);
|
||||
@ -3856,7 +3855,7 @@ AsyncPanZoomController::GetEffectiveLayoutViewport(AsyncTransformConsumer aMode)
|
||||
if (gfxPrefs::APZFrameDelayEnabled() && aMode == eForCompositing) {
|
||||
return mCompositedLayoutViewport;
|
||||
}
|
||||
return mFrameMetrics.GetViewport();
|
||||
return Metrics().GetViewport();
|
||||
}
|
||||
|
||||
CSSPoint
|
||||
@ -3865,7 +3864,7 @@ AsyncPanZoomController::GetEffectiveScrollOffset(AsyncTransformConsumer aMode) c
|
||||
if (gfxPrefs::APZFrameDelayEnabled() && aMode == eForCompositing) {
|
||||
return mCompositedScrollOffset;
|
||||
}
|
||||
return mFrameMetrics.GetScrollOffset();
|
||||
return Metrics().GetScrollOffset();
|
||||
}
|
||||
|
||||
CSSToParentLayerScale2D
|
||||
@ -3874,18 +3873,18 @@ AsyncPanZoomController::GetEffectiveZoom(AsyncTransformConsumer aMode) const
|
||||
if (gfxPrefs::APZFrameDelayEnabled() && aMode == eForCompositing) {
|
||||
return mCompositedZoom;
|
||||
}
|
||||
return mFrameMetrics.GetZoom();
|
||||
return Metrics().GetZoom();
|
||||
}
|
||||
|
||||
bool
|
||||
AsyncPanZoomController::SampleCompositedAsyncTransform()
|
||||
{
|
||||
RecursiveMutexAutoLock lock(mRecursiveMutex);
|
||||
if (mCompositedScrollOffset != mFrameMetrics.GetScrollOffset() ||
|
||||
mCompositedZoom != mFrameMetrics.GetZoom()) {
|
||||
mCompositedLayoutViewport = mFrameMetrics.GetViewport();
|
||||
mCompositedScrollOffset = mFrameMetrics.GetScrollOffset();
|
||||
mCompositedZoom = mFrameMetrics.GetZoom();
|
||||
if (mCompositedScrollOffset != Metrics().GetScrollOffset() ||
|
||||
mCompositedZoom != Metrics().GetZoom()) {
|
||||
mCompositedLayoutViewport = Metrics().GetViewport();
|
||||
mCompositedScrollOffset = Metrics().GetScrollOffset();
|
||||
mCompositedZoom = Metrics().GetZoom();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -3924,9 +3923,9 @@ AsyncPanZoomController::GetCheckerboardMagnitude() const
|
||||
{
|
||||
RecursiveMutexAutoLock lock(mRecursiveMutex);
|
||||
|
||||
CSSPoint currentScrollOffset = mFrameMetrics.GetScrollOffset() + mTestAsyncScrollOffset;
|
||||
CSSPoint currentScrollOffset = Metrics().GetScrollOffset() + mTestAsyncScrollOffset;
|
||||
CSSRect painted = mLastContentPaintMetrics.GetDisplayPort() + mLastContentPaintMetrics.GetScrollOffset();
|
||||
CSSRect visible = CSSRect(currentScrollOffset, mFrameMetrics.CalculateCompositedSizeInCssPixels());
|
||||
CSSRect visible = CSSRect(currentScrollOffset, Metrics().CalculateCompositedSizeInCssPixels());
|
||||
|
||||
CSSIntRegion checkerboard;
|
||||
// Round so as to minimize checkerboarding; if we're only showing fractional
|
||||
@ -4004,14 +4003,14 @@ bool AsyncPanZoomController::IsCurrentlyCheckerboarding() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
CSSPoint currentScrollOffset = mFrameMetrics.GetScrollOffset() + mTestAsyncScrollOffset;
|
||||
CSSPoint currentScrollOffset = Metrics().GetScrollOffset() + mTestAsyncScrollOffset;
|
||||
CSSRect painted = mLastContentPaintMetrics.GetDisplayPort() + mLastContentPaintMetrics.GetScrollOffset();
|
||||
painted.Inflate(CSSMargin::FromAppUnits(nsMargin(1, 1, 1, 1))); // fuzz for rounding error
|
||||
CSSRect visible = CSSRect(currentScrollOffset, mFrameMetrics.CalculateCompositedSizeInCssPixels());
|
||||
CSSRect visible = CSSRect(currentScrollOffset, Metrics().CalculateCompositedSizeInCssPixels());
|
||||
if (painted.Contains(visible)) {
|
||||
return false;
|
||||
}
|
||||
APZC_LOG_FM(mFrameMetrics, "%p is currently checkerboarding (painted %s visble %s)",
|
||||
APZC_LOG_FM(Metrics(), "%p is currently checkerboarding (painted %s visble %s)",
|
||||
this, Stringify(painted).c_str(), Stringify(visible).c_str());
|
||||
return true;
|
||||
}
|
||||
@ -4033,7 +4032,7 @@ void AsyncPanZoomController::NotifyLayersUpdated(const ScrollMetadata& aScrollMe
|
||||
return;
|
||||
}
|
||||
|
||||
// If the mFrameMetrics scroll offset is different from the last scroll offset
|
||||
// If the Metrics scroll offset is different from the last scroll offset
|
||||
// that the main-thread sent us, then we know that the user has been doing
|
||||
// something that triggers a scroll. This check is the APZ equivalent of the
|
||||
// check on the main-thread at
|
||||
@ -4043,8 +4042,8 @@ void AsyncPanZoomController::NotifyLayersUpdated(const ScrollMetadata& aScrollMe
|
||||
// how the main thread code does the same thing.
|
||||
CSSPoint lastScrollOffset = mLastContentPaintMetadata.GetMetrics().GetScrollOffset();
|
||||
bool userScrolled =
|
||||
!FuzzyEqualsAdditive(mFrameMetrics.GetScrollOffset().x, lastScrollOffset.x) ||
|
||||
!FuzzyEqualsAdditive(mFrameMetrics.GetScrollOffset().y, lastScrollOffset.y);
|
||||
!FuzzyEqualsAdditive(Metrics().GetScrollOffset().x, lastScrollOffset.x) ||
|
||||
!FuzzyEqualsAdditive(Metrics().GetScrollOffset().y, lastScrollOffset.y);
|
||||
|
||||
if (aLayerMetrics.GetScrollUpdateType() != FrameMetrics::ScrollOffsetUpdateType::ePending) {
|
||||
mLastContentPaintMetadata = aScrollMetadata;
|
||||
@ -4095,7 +4094,7 @@ void AsyncPanZoomController::NotifyLayersUpdated(const ScrollMetadata& aScrollMe
|
||||
// to filter duplicate calls to NotifyLayersUpdated with the same scroll offset
|
||||
// update message.
|
||||
bool scrollOffsetUpdated = aLayerMetrics.GetScrollOffsetUpdated()
|
||||
&& (aLayerMetrics.GetScrollGeneration() != mFrameMetrics.GetScrollGeneration());
|
||||
&& (aLayerMetrics.GetScrollGeneration() != Metrics().GetScrollGeneration());
|
||||
|
||||
if (scrollOffsetUpdated && userScrolled &&
|
||||
aLayerMetrics.GetScrollUpdateType() == FrameMetrics::ScrollOffsetUpdateType::eRestore) {
|
||||
@ -4104,24 +4103,24 @@ void AsyncPanZoomController::NotifyLayersUpdated(const ScrollMetadata& aScrollMe
|
||||
}
|
||||
|
||||
bool smoothScrollRequested = aLayerMetrics.GetDoSmoothScroll()
|
||||
&& (aLayerMetrics.GetScrollGeneration() != mFrameMetrics.GetScrollGeneration());
|
||||
&& (aLayerMetrics.GetScrollGeneration() != Metrics().GetScrollGeneration());
|
||||
|
||||
// TODO if we're in a drag and scrollOffsetUpdated is set then we want to
|
||||
// ignore it
|
||||
|
||||
bool needContentRepaint = false;
|
||||
bool viewportUpdated = false;
|
||||
if (FuzzyEqualsAdditive(aLayerMetrics.GetCompositionBounds().Width(), mFrameMetrics.GetCompositionBounds().Width()) &&
|
||||
FuzzyEqualsAdditive(aLayerMetrics.GetCompositionBounds().Height(), mFrameMetrics.GetCompositionBounds().Height())) {
|
||||
if (FuzzyEqualsAdditive(aLayerMetrics.GetCompositionBounds().Width(), Metrics().GetCompositionBounds().Width()) &&
|
||||
FuzzyEqualsAdditive(aLayerMetrics.GetCompositionBounds().Height(), Metrics().GetCompositionBounds().Height())) {
|
||||
// Remote content has sync'd up to the composition geometry
|
||||
// change, so we can accept the viewport it's calculated.
|
||||
if (mFrameMetrics.GetViewport().Width() != aLayerMetrics.GetViewport().Width() ||
|
||||
mFrameMetrics.GetViewport().Height() != aLayerMetrics.GetViewport().Height()) {
|
||||
if (Metrics().GetViewport().Width() != aLayerMetrics.GetViewport().Width() ||
|
||||
Metrics().GetViewport().Height() != aLayerMetrics.GetViewport().Height()) {
|
||||
needContentRepaint = true;
|
||||
viewportUpdated = true;
|
||||
}
|
||||
if (viewportUpdated || scrollOffsetUpdated) {
|
||||
mFrameMetrics.SetViewport(aLayerMetrics.GetViewport());
|
||||
Metrics().SetViewport(aLayerMetrics.GetViewport());
|
||||
}
|
||||
}
|
||||
|
||||
@ -4144,11 +4143,11 @@ void AsyncPanZoomController::NotifyLayersUpdated(const ScrollMetadata& aScrollMe
|
||||
mExpectedGeckoMetrics = aLayerMetrics;
|
||||
ShareCompositorFrameMetrics();
|
||||
|
||||
mCompositedLayoutViewport = mFrameMetrics.GetViewport();
|
||||
mCompositedScrollOffset = mFrameMetrics.GetScrollOffset();
|
||||
mCompositedZoom = mFrameMetrics.GetZoom();
|
||||
mCompositedLayoutViewport = Metrics().GetViewport();
|
||||
mCompositedScrollOffset = Metrics().GetScrollOffset();
|
||||
mCompositedZoom = Metrics().GetZoom();
|
||||
|
||||
if (mFrameMetrics.GetDisplayPortMargins() != ScreenMargin()) {
|
||||
if (Metrics().GetDisplayPortMargins() != ScreenMargin()) {
|
||||
// A non-zero display port margin here indicates a displayport has
|
||||
// been set by a previous APZC for the content at this guid. The
|
||||
// scrollable rect may have changed since then, making the margins
|
||||
@ -4158,11 +4157,11 @@ void AsyncPanZoomController::NotifyLayersUpdated(const ScrollMetadata& aScrollMe
|
||||
}
|
||||
} else {
|
||||
// If we're not taking the aLayerMetrics wholesale we still need to pull
|
||||
// in some things into our local mFrameMetrics because these things are
|
||||
// determined by Gecko and our copy in mFrameMetrics may be stale.
|
||||
// in some things into our local Metrics() because these things are
|
||||
// determined by Gecko and our copy in Metrics() may be stale.
|
||||
|
||||
if (FuzzyEqualsAdditive(mFrameMetrics.GetCompositionBounds().Width(), aLayerMetrics.GetCompositionBounds().Width()) &&
|
||||
mFrameMetrics.GetDevPixelsPerCSSPixel() == aLayerMetrics.GetDevPixelsPerCSSPixel() &&
|
||||
if (FuzzyEqualsAdditive(Metrics().GetCompositionBounds().Width(), aLayerMetrics.GetCompositionBounds().Width()) &&
|
||||
Metrics().GetDevPixelsPerCSSPixel() == aLayerMetrics.GetDevPixelsPerCSSPixel() &&
|
||||
!viewportUpdated) {
|
||||
// Any change to the pres shell resolution was requested by APZ and is
|
||||
// already included in our zoom; however, other components of the
|
||||
@ -4172,33 +4171,33 @@ void AsyncPanZoomController::NotifyLayersUpdated(const ScrollMetadata& aScrollMe
|
||||
// aLayerMetrics.mZoom because the APZ may have additional async zoom
|
||||
// since the repaint request.
|
||||
gfxSize totalResolutionChange = aLayerMetrics.GetCumulativeResolution()
|
||||
/ mFrameMetrics.GetCumulativeResolution();
|
||||
/ Metrics().GetCumulativeResolution();
|
||||
float presShellResolutionChange = aLayerMetrics.GetPresShellResolution()
|
||||
/ mFrameMetrics.GetPresShellResolution();
|
||||
/ Metrics().GetPresShellResolution();
|
||||
if (presShellResolutionChange != 1.0f) {
|
||||
needContentRepaint = true;
|
||||
}
|
||||
mFrameMetrics.ZoomBy(totalResolutionChange / presShellResolutionChange);
|
||||
Metrics().ZoomBy(totalResolutionChange / presShellResolutionChange);
|
||||
mCompositedZoom.xScale *= (totalResolutionChange / presShellResolutionChange).width;
|
||||
mCompositedZoom.yScale *= (totalResolutionChange / presShellResolutionChange).height;
|
||||
} else {
|
||||
// Take the new zoom as either device scale or composition width or
|
||||
// viewport size got changed (e.g. due to orientation change, or content
|
||||
// changing the meta-viewport tag).
|
||||
mFrameMetrics.SetZoom(aLayerMetrics.GetZoom());
|
||||
Metrics().SetZoom(aLayerMetrics.GetZoom());
|
||||
mCompositedZoom = aLayerMetrics.GetZoom();
|
||||
mFrameMetrics.SetDevPixelsPerCSSPixel(aLayerMetrics.GetDevPixelsPerCSSPixel());
|
||||
Metrics().SetDevPixelsPerCSSPixel(aLayerMetrics.GetDevPixelsPerCSSPixel());
|
||||
}
|
||||
bool scrollableRectChanged = false;
|
||||
if (!mFrameMetrics.GetScrollableRect().IsEqualEdges(aLayerMetrics.GetScrollableRect())) {
|
||||
mFrameMetrics.SetScrollableRect(aLayerMetrics.GetScrollableRect());
|
||||
if (!Metrics().GetScrollableRect().IsEqualEdges(aLayerMetrics.GetScrollableRect())) {
|
||||
Metrics().SetScrollableRect(aLayerMetrics.GetScrollableRect());
|
||||
needContentRepaint = true;
|
||||
scrollableRectChanged = true;
|
||||
}
|
||||
mFrameMetrics.SetCompositionBounds(aLayerMetrics.GetCompositionBounds());
|
||||
mFrameMetrics.SetRootCompositionSize(aLayerMetrics.GetRootCompositionSize());
|
||||
mFrameMetrics.SetPresShellResolution(aLayerMetrics.GetPresShellResolution());
|
||||
mFrameMetrics.SetCumulativeResolution(aLayerMetrics.GetCumulativeResolution());
|
||||
Metrics().SetCompositionBounds(aLayerMetrics.GetCompositionBounds());
|
||||
Metrics().SetRootCompositionSize(aLayerMetrics.GetRootCompositionSize());
|
||||
Metrics().SetPresShellResolution(aLayerMetrics.GetPresShellResolution());
|
||||
Metrics().SetCumulativeResolution(aLayerMetrics.GetCumulativeResolution());
|
||||
mScrollMetadata.SetHasScrollgrab(aScrollMetadata.GetHasScrollgrab());
|
||||
mScrollMetadata.SetLineScrollAmount(aScrollMetadata.GetLineScrollAmount());
|
||||
mScrollMetadata.SetPageScrollAmount(aScrollMetadata.GetPageScrollAmount());
|
||||
@ -4211,14 +4210,14 @@ void AsyncPanZoomController::NotifyLayersUpdated(const ScrollMetadata& aScrollMe
|
||||
mScrollMetadata.SetIsAutoDirRootContentRTL(
|
||||
aScrollMetadata.IsAutoDirRootContentRTL());
|
||||
mScrollMetadata.SetUsesContainerScrolling(aScrollMetadata.UsesContainerScrolling());
|
||||
mFrameMetrics.SetIsScrollInfoLayer(aLayerMetrics.IsScrollInfoLayer());
|
||||
Metrics().SetIsScrollInfoLayer(aLayerMetrics.IsScrollInfoLayer());
|
||||
mScrollMetadata.SetForceDisableApz(aScrollMetadata.IsApzForceDisabled());
|
||||
mScrollMetadata.SetDisregardedDirection(aScrollMetadata.GetDisregardedDirection());
|
||||
mScrollMetadata.SetOverscrollBehavior(aScrollMetadata.GetOverscrollBehavior());
|
||||
|
||||
if (scrollOffsetUpdated) {
|
||||
APZC_LOG("%p updating scroll offset from %s to %s\n", this,
|
||||
ToString(mFrameMetrics.GetScrollOffset()).c_str(),
|
||||
ToString(Metrics().GetScrollOffset()).c_str(),
|
||||
ToString(aLayerMetrics.GetScrollOffset()).c_str());
|
||||
|
||||
// Send an acknowledgement with the new scroll generation so that any
|
||||
@ -4229,8 +4228,8 @@ void AsyncPanZoomController::NotifyLayersUpdated(const ScrollMetadata& aScrollMe
|
||||
// correct this we need to update mExpectedGeckoMetrics to be the
|
||||
// last thing we know was painted by Gecko.
|
||||
CopyScrollInfoFrom(aLayerMetrics);
|
||||
mCompositedLayoutViewport = mFrameMetrics.GetViewport();
|
||||
mCompositedScrollOffset = mFrameMetrics.GetScrollOffset();
|
||||
mCompositedLayoutViewport = Metrics().GetViewport();
|
||||
mCompositedScrollOffset = Metrics().GetScrollOffset();
|
||||
mExpectedGeckoMetrics = aLayerMetrics;
|
||||
|
||||
// Cancel the animation (which might also trigger a repaint request)
|
||||
@ -4253,7 +4252,7 @@ void AsyncPanZoomController::NotifyLayersUpdated(const ScrollMetadata& aScrollMe
|
||||
// Even if we didn't accept a new scroll offset from content, the
|
||||
// scrollable rect may have changed in a way that makes our local
|
||||
// scroll offset out of bounds, so re-clamp it.
|
||||
ClampAndSetScrollOffset(mFrameMetrics.GetScrollOffset());
|
||||
ClampAndSetScrollOffset(Metrics().GetScrollOffset());
|
||||
}
|
||||
}
|
||||
|
||||
@ -4263,17 +4262,17 @@ void AsyncPanZoomController::NotifyLayersUpdated(const ScrollMetadata& aScrollMe
|
||||
// the scroll update acknowledgement.
|
||||
|
||||
APZC_LOG("%p smooth scrolling from %s to %s in state %d\n", this,
|
||||
Stringify(mFrameMetrics.GetScrollOffset()).c_str(),
|
||||
Stringify(Metrics().GetScrollOffset()).c_str(),
|
||||
Stringify(aLayerMetrics.GetSmoothScrollOffset()).c_str(),
|
||||
mState);
|
||||
|
||||
// See comment on the similar code in the |if (scrollOffsetUpdated)| block
|
||||
// above.
|
||||
mFrameMetrics.CopySmoothScrollInfoFrom(aLayerMetrics);
|
||||
Metrics().CopySmoothScrollInfoFrom(aLayerMetrics);
|
||||
needContentRepaint = true;
|
||||
mExpectedGeckoMetrics = aLayerMetrics;
|
||||
|
||||
SmoothScrollTo(mFrameMetrics.GetSmoothScrollOffset());
|
||||
SmoothScrollTo(Metrics().GetSmoothScrollOffset());
|
||||
}
|
||||
|
||||
if (needContentRepaint) {
|
||||
@ -4283,9 +4282,17 @@ void AsyncPanZoomController::NotifyLayersUpdated(const ScrollMetadata& aScrollMe
|
||||
UpdateSharedCompositorFrameMetrics();
|
||||
}
|
||||
|
||||
FrameMetrics& AsyncPanZoomController::Metrics() {
|
||||
return mScrollMetadata.GetMetrics();
|
||||
}
|
||||
|
||||
const FrameMetrics& AsyncPanZoomController::Metrics() const {
|
||||
return mScrollMetadata.GetMetrics();;
|
||||
}
|
||||
|
||||
const FrameMetrics& AsyncPanZoomController::GetFrameMetrics() const {
|
||||
mRecursiveMutex.AssertCurrentThreadIn();
|
||||
return mFrameMetrics;
|
||||
return mScrollMetadata.GetMetrics();;
|
||||
}
|
||||
|
||||
const ScrollMetadata& AsyncPanZoomController::GetScrollMetadata() const {
|
||||
@ -4331,18 +4338,18 @@ void AsyncPanZoomController::ZoomToRect(CSSRect aRect, const uint32_t aFlags) {
|
||||
// would have to be adjusted (as e.g. it would no longer be valid to take
|
||||
// the minimum or maximum of the ratios of the widths and heights of the
|
||||
// page rect and the composition bounds).
|
||||
MOZ_ASSERT(mFrameMetrics.IsRootContent());
|
||||
MOZ_ASSERT(mFrameMetrics.GetZoom().AreScalesSame());
|
||||
MOZ_ASSERT(Metrics().IsRootContent());
|
||||
MOZ_ASSERT(Metrics().GetZoom().AreScalesSame());
|
||||
|
||||
SetState(ANIMATING_ZOOM);
|
||||
|
||||
{
|
||||
RecursiveMutexAutoLock lock(mRecursiveMutex);
|
||||
|
||||
ParentLayerRect compositionBounds = mFrameMetrics.GetCompositionBounds();
|
||||
CSSRect cssPageRect = mFrameMetrics.GetScrollableRect();
|
||||
CSSPoint scrollOffset = mFrameMetrics.GetScrollOffset();
|
||||
CSSToParentLayerScale currentZoom = mFrameMetrics.GetZoom().ToScaleFactor();
|
||||
ParentLayerRect compositionBounds = Metrics().GetCompositionBounds();
|
||||
CSSRect cssPageRect = Metrics().GetScrollableRect();
|
||||
CSSPoint scrollOffset = Metrics().GetScrollOffset();
|
||||
CSSToParentLayerScale currentZoom = Metrics().GetZoom().ToScaleFactor();
|
||||
CSSToParentLayerScale targetZoom;
|
||||
|
||||
// The minimum zoom to prevent over-zoom-out.
|
||||
@ -4377,7 +4384,7 @@ void AsyncPanZoomController::ZoomToRect(CSSRect aRect, const uint32_t aFlags) {
|
||||
}
|
||||
|
||||
if (zoomOut) {
|
||||
CSSSize compositedSize = mFrameMetrics.CalculateCompositedSizeInCssPixels();
|
||||
CSSSize compositedSize = Metrics().CalculateCompositedSizeInCssPixels();
|
||||
float y = scrollOffset.y;
|
||||
float newHeight =
|
||||
cssPageRect.Width() * (compositedSize.height / compositedSize.width);
|
||||
@ -4393,12 +4400,12 @@ void AsyncPanZoomController::ZoomToRect(CSSRect aRect, const uint32_t aFlags) {
|
||||
}
|
||||
|
||||
targetZoom.scale = clamped(targetZoom.scale, localMinZoom.scale, localMaxZoom.scale);
|
||||
FrameMetrics endZoomToMetrics = mFrameMetrics;
|
||||
FrameMetrics endZoomToMetrics = Metrics();
|
||||
if (aFlags & PAN_INTO_VIEW_ONLY) {
|
||||
targetZoom = currentZoom;
|
||||
} else if(aFlags & ONLY_ZOOM_TO_DEFAULT_SCALE) {
|
||||
CSSToParentLayerScale zoomAtDefaultScale =
|
||||
mFrameMetrics.GetDevPixelsPerCSSPixel() * LayoutDeviceToParentLayerScale(1.0);
|
||||
Metrics().GetDevPixelsPerCSSPixel() * LayoutDeviceToParentLayerScale(1.0);
|
||||
if (targetZoom.scale > zoomAtDefaultScale.scale) {
|
||||
// Only change the zoom if we are less than the default zoom
|
||||
if (currentZoom.scale < zoomAtDefaultScale.scale) {
|
||||
@ -4435,8 +4442,8 @@ void AsyncPanZoomController::ZoomToRect(CSSRect aRect, const uint32_t aFlags) {
|
||||
|
||||
StartAnimation(new ZoomAnimation(
|
||||
*this,
|
||||
mFrameMetrics.GetScrollOffset(),
|
||||
mFrameMetrics.GetZoom(),
|
||||
Metrics().GetScrollOffset(),
|
||||
Metrics().GetZoom(),
|
||||
endZoomToMetrics.GetScrollOffset(),
|
||||
endZoomToMetrics.GetZoom()));
|
||||
|
||||
@ -4562,7 +4569,7 @@ void AsyncPanZoomController::DispatchStateChangeNotification(PanZoomState aOldSt
|
||||
if (APZCTreeManager* manager = GetApzcTreeManager()) {
|
||||
AndroidDynamicToolbarAnimator* animator = manager->GetAndroidDynamicToolbarAnimator();
|
||||
MOZ_ASSERT(animator);
|
||||
animator->UpdateRootFrameMetrics(mFrameMetrics);
|
||||
animator->UpdateRootFrameMetrics(Metrics());
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -4593,9 +4600,9 @@ void AsyncPanZoomController::UpdateZoomConstraints(const ZoomConstraints& aConst
|
||||
return;
|
||||
}
|
||||
|
||||
CSSToParentLayerScale min = mFrameMetrics.GetDevPixelsPerCSSPixel()
|
||||
CSSToParentLayerScale min = Metrics().GetDevPixelsPerCSSPixel()
|
||||
* kViewportMinScale / ParentLayerToScreenScale(1);
|
||||
CSSToParentLayerScale max = mFrameMetrics.GetDevPixelsPerCSSPixel()
|
||||
CSSToParentLayerScale max = Metrics().GetDevPixelsPerCSSPixel()
|
||||
* kViewportMaxScale / ParentLayerToScreenScale(1);
|
||||
|
||||
// inf float values and other bad cases should be sanitized by the code below.
|
||||
@ -4646,7 +4653,7 @@ void AsyncPanZoomController::GetGuid(ScrollableLayerGuid* aGuidOut) const
|
||||
|
||||
ScrollableLayerGuid AsyncPanZoomController::GetGuid() const
|
||||
{
|
||||
return ScrollableLayerGuid(mLayersId, mFrameMetrics);
|
||||
return ScrollableLayerGuid(mLayersId, Metrics());
|
||||
}
|
||||
|
||||
void AsyncPanZoomController::UpdateSharedCompositorFrameMetrics()
|
||||
@ -4658,7 +4665,7 @@ void AsyncPanZoomController::UpdateSharedCompositorFrameMetrics()
|
||||
|
||||
if (frame && mSharedLock && gfxPrefs::ProgressivePaint()) {
|
||||
mSharedLock->Lock();
|
||||
*frame = mFrameMetrics;
|
||||
*frame = Metrics();
|
||||
mSharedLock->Unlock();
|
||||
}
|
||||
}
|
||||
@ -4683,7 +4690,7 @@ void AsyncPanZoomController::ShareCompositorFrameMetrics()
|
||||
|
||||
{ // scope the monitor, only needed to copy the FrameMetrics.
|
||||
RecursiveMutexAutoLock lock(mRecursiveMutex);
|
||||
*frame = mFrameMetrics;
|
||||
*frame = Metrics();
|
||||
}
|
||||
|
||||
// Get the process id of the content process
|
||||
@ -4725,13 +4732,13 @@ Maybe<CSSPoint> AsyncPanZoomController::FindSnapPointNear(
|
||||
const CSSPoint& aDestination, nsIScrollableFrame::ScrollUnit aUnit) {
|
||||
mRecursiveMutex.AssertCurrentThreadIn();
|
||||
APZC_LOG("%p scroll snapping near %s\n", this, Stringify(aDestination).c_str());
|
||||
CSSRect scrollRange = mFrameMetrics.CalculateScrollRange();
|
||||
CSSRect scrollRange = Metrics().CalculateScrollRange();
|
||||
if (Maybe<nsPoint> snapPoint = ScrollSnapUtils::GetSnapPointForDestination(
|
||||
mScrollMetadata.GetSnapInfo(),
|
||||
aUnit,
|
||||
CSSSize::ToAppUnits(mFrameMetrics.CalculateCompositedSizeInCssPixels()),
|
||||
CSSSize::ToAppUnits(Metrics().CalculateCompositedSizeInCssPixels()),
|
||||
CSSRect::ToAppUnits(scrollRange),
|
||||
CSSPoint::ToAppUnits(mFrameMetrics.GetScrollOffset()),
|
||||
CSSPoint::ToAppUnits(Metrics().GetScrollOffset()),
|
||||
CSSPoint::ToAppUnits(aDestination))) {
|
||||
CSSPoint cssSnapPoint = CSSPoint::FromAppUnits(snapPoint.ref());
|
||||
// GetSnapPointForDestination() can produce a destination that's outside
|
||||
@ -4746,7 +4753,7 @@ Maybe<CSSPoint> AsyncPanZoomController::FindSnapPointNear(
|
||||
void AsyncPanZoomController::ScrollSnapNear(const CSSPoint& aDestination) {
|
||||
if (Maybe<CSSPoint> snapPoint =
|
||||
FindSnapPointNear(aDestination, nsIScrollableFrame::DEVICE_PIXELS)) {
|
||||
if (*snapPoint != mFrameMetrics.GetScrollOffset()) {
|
||||
if (*snapPoint != Metrics().GetScrollOffset()) {
|
||||
APZC_LOG("%p smooth scrolling to snap point %s\n", this, Stringify(*snapPoint).c_str());
|
||||
SmoothScrollTo(*snapPoint);
|
||||
}
|
||||
@ -4755,7 +4762,7 @@ void AsyncPanZoomController::ScrollSnapNear(const CSSPoint& aDestination) {
|
||||
|
||||
void AsyncPanZoomController::ScrollSnap() {
|
||||
RecursiveMutexAutoLock lock(mRecursiveMutex);
|
||||
ScrollSnapNear(mFrameMetrics.GetScrollOffset());
|
||||
ScrollSnapNear(Metrics().GetScrollOffset());
|
||||
}
|
||||
|
||||
void AsyncPanZoomController::ScrollSnapToDestination() {
|
||||
@ -4772,7 +4779,7 @@ void AsyncPanZoomController::ScrollSnapToDestination() {
|
||||
if (velocity.y != 0.0f) {
|
||||
predictedDelta.y = -velocity.y / log(1.0 - friction);
|
||||
}
|
||||
CSSPoint predictedDestination = mFrameMetrics.GetScrollOffset() + predictedDelta / mFrameMetrics.GetZoom();
|
||||
CSSPoint predictedDestination = Metrics().GetScrollOffset() + predictedDelta / Metrics().GetZoom();
|
||||
|
||||
// If the fling will overscroll, don't scroll snap, because then the user
|
||||
// user would not see any overscroll animation.
|
||||
@ -4783,8 +4790,8 @@ void AsyncPanZoomController::ScrollSnapToDestination() {
|
||||
"predictedDelta: %f, %f position: %f, %f "
|
||||
"predictedDestination: %f, %f\n",
|
||||
this, friction, velocity.x, velocity.y, (float)predictedDelta.x,
|
||||
(float)predictedDelta.y, (float)mFrameMetrics.GetScrollOffset().x,
|
||||
(float)mFrameMetrics.GetScrollOffset().y,
|
||||
(float)predictedDelta.y, (float)Metrics().GetScrollOffset().x,
|
||||
(float)Metrics().GetScrollOffset().y,
|
||||
(float)predictedDestination.x, (float)predictedDestination.y);
|
||||
|
||||
ScrollSnapNear(predictedDestination);
|
||||
@ -4803,8 +4810,8 @@ bool AsyncPanZoomController::MaybeAdjustDeltaForScrollSnapping(
|
||||
}
|
||||
|
||||
RecursiveMutexAutoLock lock(mRecursiveMutex);
|
||||
CSSToParentLayerScale2D zoom = mFrameMetrics.GetZoom();
|
||||
CSSPoint destination = mFrameMetrics.CalculateScrollRange().ClampPoint(
|
||||
CSSToParentLayerScale2D zoom = Metrics().GetZoom();
|
||||
CSSPoint destination = Metrics().CalculateScrollRange().ClampPoint(
|
||||
aStartPosition + (aDelta / zoom));
|
||||
nsIScrollableFrame::ScrollUnit unit =
|
||||
ScrollWheelInput::ScrollUnitForDeltaType(aEvent.mDeltaType);
|
||||
|
@ -517,6 +517,13 @@ public:
|
||||
|
||||
bool OverscrollBehaviorAllowsSwipe() const;
|
||||
|
||||
//|Metrics()| and |Metrics() const| are getter functions that both return
|
||||
//mScrollMetadata.mMetrics
|
||||
|
||||
const FrameMetrics& Metrics() const;
|
||||
FrameMetrics& Metrics();
|
||||
|
||||
|
||||
private:
|
||||
// Get whether the horizontal content of the honoured target of auto-dir
|
||||
// scrolling starts from right to left. If you don't know of auto-dir
|
||||
@ -887,13 +894,12 @@ protected:
|
||||
PlatformSpecificStateBase* GetPlatformSpecificState();
|
||||
|
||||
protected:
|
||||
// Both |mFrameMetrics| and |mLastContentPaintMetrics| are protected by the
|
||||
// monitor. Do not read from or modify either of them without locking.
|
||||
// Both |mScrollMetadata| and |mLastContentPaintMetrics| are protected by the
|
||||
// monitor. Do not read from or modify them without locking.
|
||||
ScrollMetadata mScrollMetadata;
|
||||
FrameMetrics& mFrameMetrics; // for convenience, refers to mScrollMetadata.mMetrics
|
||||
|
||||
// Protects |mFrameMetrics|, |mLastContentPaintMetrics|, and |mState|.
|
||||
// Before manipulating |mFrameMetrics| or |mLastContentPaintMetrics|, the
|
||||
// Protects |mScrollMetadata|, |mLastContentPaintMetrics| and |mState|.
|
||||
// Before manipulating |mScrollMetadata| or |mLastContentPaintMetrics| the
|
||||
// monitor should be held. When setting |mState|, either the SetState()
|
||||
// function can be used, or the monitor can be held and then |mState| updated.
|
||||
// IMPORTANT: See the note about lock ordering at the top of APZCTreeManager.h.
|
||||
@ -931,7 +937,7 @@ private:
|
||||
FrameMetrics mExpectedGeckoMetrics;
|
||||
|
||||
// These variables cache the layout viewport, scroll offset, and zoom stored
|
||||
// in |mFrameMetrics| the last time SampleCompositedAsyncTransform() was
|
||||
// in |Metrics()| the last time SampleCompositedAsyncTransform() was
|
||||
// called.
|
||||
CSSRect mCompositedLayoutViewport;
|
||||
CSSPoint mCompositedScrollOffset;
|
||||
@ -1059,20 +1065,20 @@ private:
|
||||
/**
|
||||
* Samples the composited async transform, making the result of
|
||||
* |GetCurrentAsyncTransform(eForCompositing)| and similar functions reflect
|
||||
* the async scroll offset and zoom stored in |mFrameMetrics|.
|
||||
* the async scroll offset and zoom stored in |Metrics()|.
|
||||
*
|
||||
* Returns true if the newly sampled value is different from the previously
|
||||
* sampled value.
|
||||
*
|
||||
* (This is only relevant when |gfxPrefs::APZFrameDelayEnabled() == true|.
|
||||
* Otherwise, GetCurrentAsyncTransform() always reflects what's stored in
|
||||
* |mFrameMetrics| immediately, without any delay.)
|
||||
* |Metrics()| immediately, without any delay.)
|
||||
*/
|
||||
bool SampleCompositedAsyncTransform();
|
||||
|
||||
/*
|
||||
* Helper functions to query the async layout viewport, scroll offset, and
|
||||
* zoom either directly from |mFrameMetrics|, or from cached variables that
|
||||
* zoom either directly from |Metrics()|, or from cached variables that
|
||||
* store the required value from the last time it was sampled by calling
|
||||
* SampleCompositedAsyncTransform(), depending on who is asking.
|
||||
*/
|
||||
@ -1273,7 +1279,7 @@ public:
|
||||
|
||||
bool IsRootContent() const {
|
||||
RecursiveMutexAutoLock lock(mRecursiveMutex);
|
||||
return mFrameMetrics.IsRootContent();
|
||||
return Metrics().IsRootContent();
|
||||
}
|
||||
|
||||
private:
|
||||
@ -1427,7 +1433,7 @@ private:
|
||||
RefPtr<ipc::SharedMemoryBasic> mSharedFrameMetricsBuffer;
|
||||
CrossProcessMutex* mSharedLock;
|
||||
/**
|
||||
* Called when ever mFrameMetrics is updated so that if it is being
|
||||
* Called when ever Metrics() is updated so that if it is being
|
||||
* shared with the content process the shared FrameMetrics may be updated.
|
||||
*/
|
||||
void UpdateSharedCompositorFrameMetrics();
|
||||
|
@ -104,7 +104,7 @@ public:
|
||||
* Return the amount of overscroll on this axis, in ParentLayer pixels.
|
||||
*
|
||||
* If this amount is nonzero, the relevant component of
|
||||
* mAsyncPanZoomController->mFrameMetrics.mScrollOffset must be at its
|
||||
* mAsyncPanZoomController->Metrics().mScrollOffset must be at its
|
||||
* extreme allowed value in the relevant direction (that is, it must be at
|
||||
* its maximum value if we are overscrolled at our composition length, and
|
||||
* at its minimum value if we are overscrolled at the origin).
|
||||
|
@ -227,6 +227,7 @@ protected:
|
||||
return mcc->Time();
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
RefPtr<MockContentControllerDelayed> mcc;
|
||||
};
|
||||
@ -269,12 +270,12 @@ public:
|
||||
|
||||
void SetFrameMetrics(const FrameMetrics& metrics) {
|
||||
RecursiveMutexAutoLock lock(mRecursiveMutex);
|
||||
mFrameMetrics = metrics;
|
||||
Metrics() = metrics;
|
||||
}
|
||||
|
||||
FrameMetrics& GetFrameMetrics() {
|
||||
RecursiveMutexAutoLock lock(mRecursiveMutex);
|
||||
return mFrameMetrics;
|
||||
return mScrollMetadata.GetMetrics();
|
||||
}
|
||||
|
||||
ScrollMetadata& GetScrollMetadata() {
|
||||
@ -284,7 +285,7 @@ public:
|
||||
|
||||
const FrameMetrics& GetFrameMetrics() const {
|
||||
RecursiveMutexAutoLock lock(mRecursiveMutex);
|
||||
return mFrameMetrics;
|
||||
return mScrollMetadata.GetMetrics();
|
||||
}
|
||||
|
||||
using AsyncPanZoomController::GetVelocityVector;
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "mozilla/gfx/Filters.h"
|
||||
#include "mozilla/gfx/Logging.h"
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/PodOperations.h"
|
||||
|
||||
#include "gfxContext.h"
|
||||
@ -763,7 +764,7 @@ FilterNodeFromPrimitiveDescription(const FilterPrimitiveDescription& aDescriptio
|
||||
uint32_t type = atts.GetUint(eColorMatrixType);
|
||||
const nsTArray<float>& values = atts.GetFloats(eColorMatrixValues);
|
||||
if (NS_FAILED(ComputeColorMatrix(type, values, colorMatrix)) ||
|
||||
PodEqual(colorMatrix, identityMatrix)) {
|
||||
ArrayEqual(colorMatrix, identityMatrix)) {
|
||||
RefPtr<FilterNode> filter(aSources[0]);
|
||||
return filter.forget();
|
||||
}
|
||||
@ -974,7 +975,7 @@ FilterNodeFromPrimitiveDescription(const FilterPrimitiveDescription& aDescriptio
|
||||
// All-zero coefficients sometimes occur in junk filters.
|
||||
if (!filter ||
|
||||
(coefficients.Length() == ArrayLength(allZero) &&
|
||||
PodEqual(coefficients.Elements(), allZero, ArrayLength(allZero)))) {
|
||||
ArrayEqual(coefficients.Elements(), allZero, ArrayLength(allZero)))) {
|
||||
return nullptr;
|
||||
}
|
||||
filter->SetAttribute(ATT_ARITHMETIC_COMBINE_COEFFICIENTS,
|
||||
|
@ -5,8 +5,8 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/gfx/Swizzle.h"
|
||||
#include "mozilla/PodOperations.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::gfx;
|
||||
@ -50,17 +50,17 @@ TEST(Moz2D, PremultiplyData) {
|
||||
PremultiplyData(in_bgra, sizeof(in_bgra), SurfaceFormat::B8G8R8A8,
|
||||
out, sizeof(in_bgra), SurfaceFormat::B8G8R8A8,
|
||||
IntSize(5, 1));
|
||||
EXPECT_TRUE(PodEqual(out, check_bgra));
|
||||
EXPECT_TRUE(ArrayEqual(out, check_bgra));
|
||||
|
||||
PremultiplyData(in_bgra, sizeof(in_bgra), SurfaceFormat::B8G8R8A8,
|
||||
out, sizeof(in_bgra), SurfaceFormat::R8G8B8A8,
|
||||
IntSize(5, 1));
|
||||
EXPECT_TRUE(PodEqual(out, check_rgba));
|
||||
EXPECT_TRUE(ArrayEqual(out, check_rgba));
|
||||
|
||||
PremultiplyData(in_bgra, sizeof(in_bgra), SurfaceFormat::B8G8R8A8,
|
||||
out, sizeof(in_bgra), SurfaceFormat::A8R8G8B8,
|
||||
IntSize(5, 1));
|
||||
EXPECT_TRUE(PodEqual(out, check_argb));
|
||||
EXPECT_TRUE(ArrayEqual(out, check_argb));
|
||||
}
|
||||
|
||||
TEST(Moz2D, UnpremultiplyData) {
|
||||
@ -103,17 +103,17 @@ TEST(Moz2D, UnpremultiplyData) {
|
||||
UnpremultiplyData(in_bgra, sizeof(in_bgra), SurfaceFormat::B8G8R8A8,
|
||||
out, sizeof(in_bgra), SurfaceFormat::B8G8R8A8,
|
||||
IntSize(5, 1));
|
||||
EXPECT_TRUE(PodEqual(out, check_bgra));
|
||||
EXPECT_TRUE(ArrayEqual(out, check_bgra));
|
||||
|
||||
UnpremultiplyData(in_bgra, sizeof(in_bgra), SurfaceFormat::B8G8R8A8,
|
||||
out, sizeof(in_bgra), SurfaceFormat::R8G8B8A8,
|
||||
IntSize(5, 1));
|
||||
EXPECT_TRUE(PodEqual(out, check_rgba));
|
||||
EXPECT_TRUE(ArrayEqual(out, check_rgba));
|
||||
|
||||
UnpremultiplyData(in_bgra, sizeof(in_bgra), SurfaceFormat::B8G8R8A8,
|
||||
out, sizeof(in_bgra), SurfaceFormat::A8R8G8B8,
|
||||
IntSize(5, 1));
|
||||
EXPECT_TRUE(PodEqual(out, check_argb));
|
||||
EXPECT_TRUE(ArrayEqual(out, check_argb));
|
||||
}
|
||||
|
||||
TEST(Moz2D, SwizzleData) {
|
||||
@ -199,42 +199,42 @@ TEST(Moz2D, SwizzleData) {
|
||||
SwizzleData(in_bgra, sizeof(in_bgra), SurfaceFormat::B8G8R8A8,
|
||||
out, sizeof(out), SurfaceFormat::B8G8R8A8,
|
||||
IntSize(5, 1));
|
||||
EXPECT_TRUE(PodEqual(out, check_bgra));
|
||||
EXPECT_TRUE(ArrayEqual(out, check_bgra));
|
||||
|
||||
SwizzleData(in_bgra, sizeof(in_bgra), SurfaceFormat::B8G8R8A8,
|
||||
out, sizeof(out), SurfaceFormat::R8G8B8A8,
|
||||
IntSize(5, 1));
|
||||
EXPECT_TRUE(PodEqual(out, check_rgba));
|
||||
EXPECT_TRUE(ArrayEqual(out, check_rgba));
|
||||
|
||||
SwizzleData(in_bgra, sizeof(in_bgra), SurfaceFormat::B8G8R8A8,
|
||||
out, sizeof(out), SurfaceFormat::A8R8G8B8,
|
||||
IntSize(5, 1));
|
||||
EXPECT_TRUE(PodEqual(out, check_argb));
|
||||
EXPECT_TRUE(ArrayEqual(out, check_argb));
|
||||
|
||||
SwizzleData(in_bgra, sizeof(in_bgra), SurfaceFormat::B8G8R8A8,
|
||||
out, sizeof(out), SurfaceFormat::R8G8B8X8,
|
||||
IntSize(5, 1));
|
||||
EXPECT_TRUE(PodEqual(out, check_rgbx));
|
||||
EXPECT_TRUE(ArrayEqual(out, check_rgbx));
|
||||
|
||||
SwizzleData(in_bgra, sizeof(in_bgra), SurfaceFormat::B8G8R8A8,
|
||||
out24, sizeof(out24), SurfaceFormat::B8G8R8,
|
||||
IntSize(5, 1));
|
||||
EXPECT_TRUE(PodEqual(out24, check_bgr));
|
||||
EXPECT_TRUE(ArrayEqual(out24, check_bgr));
|
||||
|
||||
SwizzleData(in_bgra, sizeof(in_bgra), SurfaceFormat::B8G8R8A8,
|
||||
out24, sizeof(out24), SurfaceFormat::R8G8B8,
|
||||
IntSize(5, 1));
|
||||
EXPECT_TRUE(PodEqual(out24, check_rgb));
|
||||
EXPECT_TRUE(ArrayEqual(out24, check_rgb));
|
||||
|
||||
SwizzleData(in_bgra, sizeof(in_bgra), SurfaceFormat::B8G8R8A8,
|
||||
out8, sizeof(out8), SurfaceFormat::A8,
|
||||
IntSize(5, 1));
|
||||
EXPECT_TRUE(PodEqual(out8, check_a));
|
||||
EXPECT_TRUE(ArrayEqual(out8, check_a));
|
||||
|
||||
SwizzleData(SurfaceFormat::A8R8G8B8_UINT32 == SurfaceFormat::A8R8G8B8 ? check_argb : check_bgra,
|
||||
sizeof(in_bgra), SurfaceFormat::A8R8G8B8_UINT32,
|
||||
reinterpret_cast<uint8_t*>(out16), sizeof(out16), SurfaceFormat::R5G6B5_UINT16,
|
||||
IntSize(5, 1));
|
||||
EXPECT_TRUE(PodEqual(out16, check_16));
|
||||
EXPECT_TRUE(ArrayEqual(out16, check_16));
|
||||
}
|
||||
|
||||
|
@ -484,13 +484,14 @@ ConstructSavedFrameStackSlow(JSContext* cx,
|
||||
// by an offline heap snapshot from an older SpiderMonkey/Firefox version to
|
||||
// break. Consider this enum append only.
|
||||
enum class CoarseType: uint32_t {
|
||||
Other = 0,
|
||||
Object = 1,
|
||||
Script = 2,
|
||||
String = 3,
|
||||
Other = 0,
|
||||
Object = 1,
|
||||
Script = 2,
|
||||
String = 3,
|
||||
DOMNode = 4,
|
||||
|
||||
FIRST = Other,
|
||||
LAST = String
|
||||
FIRST = Other,
|
||||
LAST = DOMNode
|
||||
};
|
||||
|
||||
inline uint32_t
|
||||
@ -619,6 +620,13 @@ class JS_PUBLIC_API(Base) {
|
||||
"hasAllocationStack and allocationStack.");
|
||||
}
|
||||
|
||||
// In some cases, Concrete<T> can return a more descriptive
|
||||
// referent type name than simply `T`. This method returns an
|
||||
// identifier as specific as is efficiently available.
|
||||
// The string returned is borrowed from the ubi::Node's referent.
|
||||
// If nothing more specific than typeName() is available, return nullptr.
|
||||
virtual const char16_t* descriptiveTypeName() const { return nullptr; }
|
||||
|
||||
// Methods for JSObject Referents
|
||||
//
|
||||
// These methods are only semantically valid if the referent is either a
|
||||
@ -778,12 +786,13 @@ class Node {
|
||||
// not all!) JSObjects can be exposed.
|
||||
JS::Value exposeToJS() const;
|
||||
|
||||
CoarseType coarseType() const { return base()->coarseType(); }
|
||||
const char16_t* typeName() const { return base()->typeName(); }
|
||||
JS::Zone* zone() const { return base()->zone(); }
|
||||
JS::Compartment* compartment() const { return base()->compartment(); }
|
||||
JS::Realm* realm() const { return base()->realm(); }
|
||||
const char* jsObjectClassName() const { return base()->jsObjectClassName(); }
|
||||
CoarseType coarseType() const { return base()->coarseType(); }
|
||||
const char16_t* typeName() const { return base()->typeName(); }
|
||||
JS::Zone* zone() const { return base()->zone(); }
|
||||
JS::Compartment* compartment() const { return base()->compartment(); }
|
||||
JS::Realm* realm() const { return base()->realm(); }
|
||||
const char* jsObjectClassName() const { return base()->jsObjectClassName(); }
|
||||
const char16_t* descriptiveTypeName() const { return base()->descriptiveTypeName(); }
|
||||
MOZ_MUST_USE bool jsObjectConstructorName(JSContext* cx, UniqueTwoByteChars& outName) const {
|
||||
return base()->jsObjectConstructorName(cx, outName);
|
||||
}
|
||||
|
@ -30,6 +30,8 @@
|
||||
// - objects with a specific [[Class]] *
|
||||
// - strings
|
||||
// - scripts
|
||||
// - DOM nodes
|
||||
// - nsINodes with a specific name (found in nsINode::NodeName()) *
|
||||
// - all other Node types
|
||||
// - nodes with a specific ubi::Node::typeName *
|
||||
//
|
||||
@ -47,7 +49,8 @@
|
||||
// {
|
||||
// by: "coarseType",
|
||||
// objects: { by: "objectClass" },
|
||||
// other: { by: "internalType" }
|
||||
// other: { by: "internalType" },
|
||||
// domNode: { by: "descriptiveType" }
|
||||
// }
|
||||
//
|
||||
// we would build the following tree of CountType subclasses:
|
||||
@ -59,6 +62,8 @@
|
||||
// strings: SimpleCount
|
||||
// other: ByUbinodeType
|
||||
// each type: SimpleCount
|
||||
// domNode: ByDomObjectClass
|
||||
// each type: SimpleCount
|
||||
//
|
||||
// The interior nodes are all breakdown types that categorize nodes according to
|
||||
// one characteristic or another; and the leaf nodes are all SimpleType.
|
||||
|
@ -275,13 +275,15 @@ Function Properties of the `Debugger.Memory.prototype` Object
|
||||
|
||||
{ "count": 1616, "bytes": 93240 }
|
||||
|
||||
Here is a breakdown that groups JavaScript objects by their class name, and
|
||||
non-string, non-script items by their C++ type name:
|
||||
Here is a breakdown that groups JavaScript objects by their class name,
|
||||
non-string, non-script items by their C++ type name, and DOM nodes with
|
||||
their node name:
|
||||
|
||||
{
|
||||
by: "coarseType",
|
||||
objects: { by: "objectClass" },
|
||||
other: { by: "internalType" }
|
||||
other: { by: "internalType" },
|
||||
domNode: { by: "descriptiveType" }
|
||||
}
|
||||
|
||||
which produces a result like this:
|
||||
@ -300,6 +302,9 @@ Function Properties of the `Debugger.Memory.prototype` Object
|
||||
"js::Shape": { "count": 450, "bytes": 0 },
|
||||
"js::BaseShape": { "count": 21, "bytes": 0 },
|
||||
"js::ObjectGroup": { "count": 17, "bytes": 0 }
|
||||
},
|
||||
"domNode": {
|
||||
"#text": { "count": 1, "bytes": 12 }
|
||||
}
|
||||
}
|
||||
|
||||
@ -370,7 +375,7 @@ Function Properties of the `Debugger.Memory.prototype` Object
|
||||
The results for non-object items appear as the value of the property
|
||||
named `"other"`.
|
||||
|
||||
<code>{ by: "coarseType", objects:<i>objects</i>, scripts:<i>scripts</i>, strings:<i>strings</i>, other:<i>other</i> }</code>
|
||||
<code>{ by: "coarseType", objects:<i>objects</i>, scripts:<i>scripts</i>, strings:<i>strings</i>, domNode:<i>domNode</i>, other:<i>other</i> }</code>
|
||||
: Group items by their coarse type.
|
||||
|
||||
Use the breakdown value <i>objects</i> for items that are JavaScript
|
||||
@ -382,6 +387,8 @@ Function Properties of the `Debugger.Memory.prototype` Object
|
||||
|
||||
Use the breakdown value <i>strings</i> for JavaScript strings.
|
||||
|
||||
Use the breakdown value <i>domNode</i> for DOM nodes.
|
||||
|
||||
Use the breakdown value <i>other</i> for items that don't fit into any of
|
||||
the above categories.
|
||||
|
||||
@ -393,6 +400,7 @@ Function Properties of the `Debugger.Memory.prototype` Object
|
||||
"objects": <i>result</i>,
|
||||
"scripts": <i>result</i>,
|
||||
"strings": <i>result</i>,
|
||||
"domNode:" <i>result</i>,
|
||||
"other": <i>result</i>
|
||||
}
|
||||
</code></pre>
|
||||
@ -438,6 +446,7 @@ Function Properties of the `Debugger.Memory.prototype` Object
|
||||
{
|
||||
by: "coarseType",
|
||||
objects: { by: "objectClass" },
|
||||
domNode: { by: "descriptiveType" },
|
||||
other: { by: "internalType" }
|
||||
}
|
||||
</code></pre>
|
||||
@ -449,6 +458,7 @@ Function Properties of the `Debugger.Memory.prototype` Object
|
||||
objects: { <i>class</i>: <i>count</i>, ... },
|
||||
scripts: <i>count</i>,
|
||||
strings: <i>count</i>,
|
||||
domNode: { <i>node name</i>: <i>count</i>, ... },
|
||||
other: { <i>type name</i>: <i>count</i>, ... }
|
||||
}
|
||||
</code></pre>
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "jit/CacheIRCompiler.h"
|
||||
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/ScopeExit.h"
|
||||
|
||||
#include <utility>
|
||||
@ -1165,7 +1166,7 @@ CacheIRStubKey::match(const CacheIRStubKey& entry, const CacheIRStubKey::Lookup&
|
||||
if (entry.stubInfo->codeLength() != l.length)
|
||||
return false;
|
||||
|
||||
if (!mozilla::PodEqual(entry.stubInfo->code(), l.code, l.length))
|
||||
if (!mozilla::ArrayEqual(entry.stubInfo->code(), l.code, l.length))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
@ -3,12 +3,11 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/PodOperations.h"
|
||||
|
||||
#include "jsapi-tests/tests.h"
|
||||
|
||||
using mozilla::ArrayEqual;
|
||||
using mozilla::ArrayLength;
|
||||
using mozilla::PodEqual;
|
||||
|
||||
static const char16_t arr[] = {
|
||||
'h', 'i', ',', 'd', 'o', 'n', '\'', 't', ' ', 'd', 'e', 'l', 'e', 't', 'e', ' ', 'm', 'e', '\0'
|
||||
@ -27,7 +26,7 @@ static const JSStringFinalizer finalizer2 = { finalize_str };
|
||||
static void
|
||||
finalize_str(const JSStringFinalizer* fin, char16_t* chars)
|
||||
{
|
||||
if (chars && PodEqual(const_cast<const char16_t*>(chars), arr, arrlen)) {
|
||||
if (chars && ArrayEqual(chars, arr, arrlen)) {
|
||||
if (fin == &finalizer1) {
|
||||
++finalized1;
|
||||
} else if (fin == &finalizer2) {
|
||||
|
@ -127,14 +127,13 @@ using namespace js::shell;
|
||||
|
||||
using js::shell::RCFile;
|
||||
|
||||
using mozilla::ArrayEqual;
|
||||
using mozilla::ArrayLength;
|
||||
using mozilla::Atomic;
|
||||
using mozilla::MakeScopeExit;
|
||||
using mozilla::Maybe;
|
||||
using mozilla::Nothing;
|
||||
using mozilla::NumberEqualsInt32;
|
||||
using mozilla::PodCopy;
|
||||
using mozilla::PodEqual;
|
||||
using mozilla::TimeDuration;
|
||||
using mozilla::TimeStamp;
|
||||
|
||||
@ -2074,7 +2073,7 @@ Evaluate(JSContext* cx, unsigned argc, Value* vp)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!PodEqual(loadBuffer.begin(), saveBuffer.begin(), loadBuffer.length())) {
|
||||
if (!ArrayEqual(loadBuffer.begin(), saveBuffer.begin(), loadBuffer.length())) {
|
||||
JS_ReportErrorNumberASCII(cx, my_GetErrorMessage, nullptr,
|
||||
JSSMSG_CACHE_EQ_CONTENT_FAILED);
|
||||
return false;
|
||||
@ -5582,7 +5581,7 @@ SingleStepCallback(void* arg, jit::Simulator* sim, void* pc)
|
||||
// Only append the stack if it differs from the last stack.
|
||||
if (sc->stacks.empty() ||
|
||||
sc->stacks.back().length() != stack.length() ||
|
||||
!PodEqual(sc->stacks.back().begin(), stack.begin(), stack.length()))
|
||||
!ArrayEqual(sc->stacks.back().begin(), stack.begin(), stack.length()))
|
||||
{
|
||||
if (!sc->stacks.append(std::move(stack)))
|
||||
oomUnsafe.crash("stacks.append");
|
||||
|
@ -7,6 +7,7 @@
|
||||
#ifndef util_Text_h
|
||||
#define util_Text_h
|
||||
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/TextUtils.h"
|
||||
@ -54,26 +55,11 @@ namespace js {
|
||||
|
||||
class StringBuffer;
|
||||
|
||||
template <typename Char1, typename Char2>
|
||||
inline bool
|
||||
EqualChars(const Char1* s1, const Char2* s2, size_t len);
|
||||
|
||||
template <typename Char1>
|
||||
inline bool
|
||||
EqualChars(const Char1* s1, const Char1* s2, size_t len)
|
||||
{
|
||||
return mozilla::PodEqual(s1, s2, len);
|
||||
}
|
||||
|
||||
template <typename Char1, typename Char2>
|
||||
inline bool
|
||||
EqualChars(const Char1* s1, const Char2* s2, size_t len)
|
||||
{
|
||||
for (const Char1* s1end = s1 + len; s1 < s1end; s1++, s2++) {
|
||||
if (*s1 != *s2)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return mozilla::ArrayEqual(s1, s2, len);
|
||||
}
|
||||
|
||||
// Return less than, equal to, or greater than zero depending on whether
|
||||
|
@ -102,6 +102,7 @@
|
||||
macro(direction, direction, "direction") \
|
||||
macro(displayURL, displayURL, "displayURL") \
|
||||
macro(do, do_, "do") \
|
||||
macro(domNode, domNode, "domNode") \
|
||||
macro(done, done, "done") \
|
||||
macro(dotGenerator, dotGenerator, ".generator") \
|
||||
macro(dotThis, dotThis, ".this") \
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include "vm/Iteration.h"
|
||||
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/Likely.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
@ -47,10 +48,10 @@
|
||||
using namespace js;
|
||||
using namespace js::gc;
|
||||
|
||||
using mozilla::ArrayEqual;
|
||||
using mozilla::DebugOnly;
|
||||
using mozilla::Maybe;
|
||||
using mozilla::PodCopy;
|
||||
using mozilla::PodEqual;
|
||||
|
||||
typedef Rooted<PropertyIteratorObject*> RootedPropertyIteratorObject;
|
||||
|
||||
@ -793,8 +794,8 @@ IteratorHashPolicy::match(PropertyIteratorObject* obj, const Lookup& lookup)
|
||||
if (ni->guardKey() != lookup.key || ni->guardCount() != lookup.numGuards)
|
||||
return false;
|
||||
|
||||
return PodEqual(reinterpret_cast<ReceiverGuard*>(ni->guardsBegin()), lookup.guards,
|
||||
ni->guardCount());
|
||||
return ArrayEqual(reinterpret_cast<ReceiverGuard*>(ni->guardsBegin()), lookup.guards,
|
||||
ni->guardCount());
|
||||
}
|
||||
|
||||
static inline bool
|
||||
|
@ -96,14 +96,14 @@ js::AtomHasher::match(const AtomStateEntry& entry, const Lookup& lookup)
|
||||
if (key->hasLatin1Chars()) {
|
||||
const Latin1Char* keyChars = key->latin1Chars(lookup.nogc);
|
||||
if (lookup.isLatin1)
|
||||
return mozilla::PodEqual(keyChars, lookup.latin1Chars, lookup.length);
|
||||
return mozilla::ArrayEqual(keyChars, lookup.latin1Chars, lookup.length);
|
||||
return EqualChars(keyChars, lookup.twoByteChars, lookup.length);
|
||||
}
|
||||
|
||||
const char16_t* keyChars = key->twoByteChars(lookup.nogc);
|
||||
if (lookup.isLatin1)
|
||||
return EqualChars(lookup.latin1Chars, keyChars, lookup.length);
|
||||
return mozilla::PodEqual(keyChars, lookup.twoByteChars, lookup.length);
|
||||
return mozilla::ArrayEqual(keyChars, lookup.twoByteChars, lookup.length);
|
||||
}
|
||||
|
||||
inline JSAtom*
|
||||
|
@ -9,10 +9,10 @@
|
||||
#ifndef vm_JSScript_h
|
||||
#define vm_JSScript_h
|
||||
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/Atomics.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/PodOperations.h"
|
||||
#include "mozilla/Variant.h"
|
||||
|
||||
#include "jstypes.h"
|
||||
@ -886,7 +886,7 @@ struct ScriptBytecodeHasher
|
||||
return false;
|
||||
if (entry->numNotes() != data->numNotes())
|
||||
return false;
|
||||
return mozilla::PodEqual<uint8_t>(entry->data(), data->data(), data->dataLength());
|
||||
return mozilla::ArrayEqual<uint8_t>(entry->data(), data->data(), data->dataLength());
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "vm/StringType-inl.h"
|
||||
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/FloatingPoint.h"
|
||||
#include "mozilla/HashFunctions.h"
|
||||
#include "mozilla/MathAlgorithms.h"
|
||||
@ -30,11 +31,11 @@
|
||||
|
||||
using namespace js;
|
||||
|
||||
using mozilla::ArrayEqual;
|
||||
using mozilla::IsAsciiDigit;
|
||||
using mozilla::IsNegativeZero;
|
||||
using mozilla::IsSame;
|
||||
using mozilla::PodCopy;
|
||||
using mozilla::PodEqual;
|
||||
using mozilla::RangedPtr;
|
||||
using mozilla::RoundUpPow2;
|
||||
using mozilla::Unused;
|
||||
@ -846,13 +847,13 @@ js::EqualChars(JSLinearString* str1, JSLinearString* str2)
|
||||
AutoCheckCannotGC nogc;
|
||||
if (str1->hasTwoByteChars()) {
|
||||
if (str2->hasTwoByteChars())
|
||||
return PodEqual(str1->twoByteChars(nogc), str2->twoByteChars(nogc), len);
|
||||
return ArrayEqual(str1->twoByteChars(nogc), str2->twoByteChars(nogc), len);
|
||||
|
||||
return EqualChars(str2->latin1Chars(nogc), str1->twoByteChars(nogc), len);
|
||||
}
|
||||
|
||||
if (str2->hasLatin1Chars())
|
||||
return PodEqual(str1->latin1Chars(nogc), str2->latin1Chars(nogc), len);
|
||||
return ArrayEqual(str1->latin1Chars(nogc), str2->latin1Chars(nogc), len);
|
||||
|
||||
return EqualChars(str1->latin1Chars(nogc), str2->twoByteChars(nogc), len);
|
||||
}
|
||||
@ -868,14 +869,14 @@ js::HasSubstringAt(JSLinearString* text, JSLinearString* pat, size_t start)
|
||||
if (text->hasLatin1Chars()) {
|
||||
const Latin1Char* textChars = text->latin1Chars(nogc) + start;
|
||||
if (pat->hasLatin1Chars())
|
||||
return PodEqual(textChars, pat->latin1Chars(nogc), patLen);
|
||||
return ArrayEqual(textChars, pat->latin1Chars(nogc), patLen);
|
||||
|
||||
return EqualChars(textChars, pat->twoByteChars(nogc), patLen);
|
||||
}
|
||||
|
||||
const char16_t* textChars = text->twoByteChars(nogc) + start;
|
||||
if (pat->hasTwoByteChars())
|
||||
return PodEqual(textChars, pat->twoByteChars(nogc), patLen);
|
||||
return ArrayEqual(textChars, pat->twoByteChars(nogc), patLen);
|
||||
|
||||
return EqualChars(pat->latin1Chars(nogc), textChars, patLen);
|
||||
}
|
||||
@ -991,7 +992,7 @@ js::StringEqualsAscii(JSLinearString* str, const char* asciiBytes)
|
||||
|
||||
AutoCheckCannotGC nogc;
|
||||
return str->hasLatin1Chars()
|
||||
? PodEqual(latin1, str->latin1Chars(nogc), length)
|
||||
? ArrayEqual(latin1, str->latin1Chars(nogc), length)
|
||||
: EqualChars(latin1, str->twoByteChars(nogc), length);
|
||||
}
|
||||
|
||||
@ -1757,7 +1758,7 @@ ExternalStringCache::lookup(const char16_t* chars, size_t len) const
|
||||
// Compare the chars. Don't do this for long strings as it will be
|
||||
// faster to allocate a new external string.
|
||||
static const size_t MaxLengthForCharComparison = 100;
|
||||
if (len <= MaxLengthForCharComparison && PodEqual(chars, strChars, len))
|
||||
if (len <= MaxLengthForCharComparison && ArrayEqual(chars, strChars, len))
|
||||
return str;
|
||||
}
|
||||
|
||||
|
@ -177,7 +177,7 @@ BucketCount::report(JSContext* cx, CountBase& countBase, MutableHandleValue repo
|
||||
|
||||
|
||||
// A type that categorizes nodes by their JavaScript type -- 'objects',
|
||||
// 'strings', 'scripts', and 'other' -- and then passes the nodes to child
|
||||
// 'strings', 'scripts', 'domNode', and 'other' -- and then passes the nodes to child
|
||||
// types.
|
||||
//
|
||||
// Implementation details of scripts like jitted code are counted under
|
||||
@ -187,36 +187,42 @@ class ByCoarseType : public CountType {
|
||||
CountTypePtr scripts;
|
||||
CountTypePtr strings;
|
||||
CountTypePtr other;
|
||||
CountTypePtr domNode;
|
||||
|
||||
struct Count : CountBase {
|
||||
Count(CountType& type,
|
||||
CountBasePtr& objects,
|
||||
CountBasePtr& scripts,
|
||||
CountBasePtr& strings,
|
||||
CountBasePtr& other)
|
||||
CountBasePtr& other,
|
||||
CountBasePtr& domNode)
|
||||
: CountBase(type),
|
||||
objects(std::move(objects)),
|
||||
scripts(std::move(scripts)),
|
||||
strings(std::move(strings)),
|
||||
other(std::move(other))
|
||||
other(std::move(other)),
|
||||
domNode(std::move(domNode))
|
||||
{ }
|
||||
|
||||
CountBasePtr objects;
|
||||
CountBasePtr scripts;
|
||||
CountBasePtr strings;
|
||||
CountBasePtr other;
|
||||
CountBasePtr domNode;
|
||||
};
|
||||
|
||||
public:
|
||||
ByCoarseType(CountTypePtr& objects,
|
||||
CountTypePtr& scripts,
|
||||
CountTypePtr& strings,
|
||||
CountTypePtr& other)
|
||||
CountTypePtr& other,
|
||||
CountTypePtr& domNode)
|
||||
: CountType(),
|
||||
objects(std::move(objects)),
|
||||
scripts(std::move(scripts)),
|
||||
strings(std::move(strings)),
|
||||
other(std::move(other))
|
||||
other(std::move(other)),
|
||||
domNode(std::move(domNode))
|
||||
{ }
|
||||
|
||||
void destructCount(CountBase& countBase) override {
|
||||
@ -237,15 +243,17 @@ ByCoarseType::makeCount()
|
||||
CountBasePtr scriptsCount(scripts->makeCount());
|
||||
CountBasePtr stringsCount(strings->makeCount());
|
||||
CountBasePtr otherCount(other->makeCount());
|
||||
CountBasePtr domNodeCount(domNode->makeCount());
|
||||
|
||||
if (!objectsCount || !scriptsCount || !stringsCount || !otherCount)
|
||||
if (!objectsCount || !scriptsCount || !stringsCount || !otherCount || !domNodeCount)
|
||||
return CountBasePtr(nullptr);
|
||||
|
||||
return CountBasePtr(js_new<Count>(*this,
|
||||
objectsCount,
|
||||
scriptsCount,
|
||||
stringsCount,
|
||||
otherCount));
|
||||
otherCount,
|
||||
domNodeCount));
|
||||
}
|
||||
|
||||
void
|
||||
@ -256,6 +264,7 @@ ByCoarseType::traceCount(CountBase& countBase, JSTracer* trc)
|
||||
count.scripts->trace(trc);
|
||||
count.strings->trace(trc);
|
||||
count.other->trace(trc);
|
||||
count.domNode->trace(trc);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -272,6 +281,8 @@ ByCoarseType::count(CountBase& countBase, mozilla::MallocSizeOf mallocSizeOf, co
|
||||
return count.strings->count(mallocSizeOf, node);
|
||||
case JS::ubi::CoarseType::Other:
|
||||
return count.other->count(mallocSizeOf, node);
|
||||
case JS::ubi::CoarseType::DOMNode:
|
||||
return count.domNode->count(mallocSizeOf, node);
|
||||
default:
|
||||
MOZ_CRASH("bad JS::ubi::CoarseType in JS::ubi::ByCoarseType::count");
|
||||
return false;
|
||||
@ -306,6 +317,10 @@ ByCoarseType::report(JSContext* cx, CountBase& countBase, MutableHandleValue rep
|
||||
if (!count.other->report(cx, &otherReport) ||
|
||||
!DefineDataProperty(cx, obj, cx->names().other, otherReport))
|
||||
return false;
|
||||
RootedValue domReport(cx);
|
||||
if (!count.domNode->report(cx, &domReport) ||
|
||||
!DefineDataProperty(cx, obj, cx->names().domNode, domReport))
|
||||
return false;
|
||||
|
||||
report.setObject(*obj);
|
||||
return true;
|
||||
@ -386,6 +401,51 @@ countMapToObject(JSContext* cx, Map& map, GetName getName) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
template <class Map, class GetName>
|
||||
static PlainObject*
|
||||
countMap16ToObject(JSContext* cx, Map& map, GetName getName) {
|
||||
// Build a vector of pointers to entries; sort by total; and then use
|
||||
// that to build the result object. This makes the ordering of entries
|
||||
// more interesting, and a little less non-deterministic.
|
||||
|
||||
JS::ubi::Vector<typename Map::Entry*> entries;
|
||||
if (!entries.reserve(map.count())) {
|
||||
ReportOutOfMemory(cx);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
for (auto r = map.all(); !r.empty(); r.popFront())
|
||||
entries.infallibleAppend(&r.front());
|
||||
|
||||
if (entries.length()) {
|
||||
qsort(entries.begin(), entries.length(), sizeof(*entries.begin()),
|
||||
compareEntries<typename Map::Entry>);
|
||||
}
|
||||
|
||||
RootedPlainObject obj(cx, NewBuiltinClassInstance<PlainObject>(cx));
|
||||
if (!obj)
|
||||
return nullptr;
|
||||
|
||||
for (auto& entry : entries) {
|
||||
CountBasePtr& thenCount = entry->value();
|
||||
RootedValue thenReport(cx);
|
||||
if (!thenCount->report(cx, &thenReport))
|
||||
return nullptr;
|
||||
|
||||
const char16_t* name = getName(entry->key());
|
||||
MOZ_ASSERT(name);
|
||||
JSAtom* atom = AtomizeChars(cx, name, js_strlen(name));
|
||||
if (!atom)
|
||||
return nullptr;
|
||||
|
||||
RootedId entryId(cx, AtomToId(atom));
|
||||
if (!DefineDataProperty(cx, obj, entryId, thenReport))
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
// A type that categorizes nodes that are JSObjects by their class name,
|
||||
// and places all other nodes in an 'other' category.
|
||||
@ -492,6 +552,111 @@ ByObjectClass::report(JSContext* cx, CountBase& countBase, MutableHandleValue re
|
||||
return true;
|
||||
}
|
||||
|
||||
class ByDomObjectClass : public CountType {
|
||||
// A table mapping descriptive names to their counts.
|
||||
using UniqueC16String = JS::UniqueTwoByteChars;
|
||||
|
||||
struct UniqueC16StringHasher
|
||||
{
|
||||
using Lookup = UniqueC16String;
|
||||
|
||||
static js::HashNumber hash(const Lookup& lookup) {
|
||||
return mozilla::HashString(lookup.get());
|
||||
}
|
||||
|
||||
static bool match(const UniqueC16String& key, const Lookup& lookup) {
|
||||
return CompareChars(key.get(), js_strlen(key.get()), lookup.get(),
|
||||
js_strlen(lookup.get())) == 0;
|
||||
}
|
||||
};
|
||||
|
||||
using Table = HashMap<UniqueC16String,
|
||||
CountBasePtr,
|
||||
UniqueC16StringHasher,
|
||||
SystemAllocPolicy>;
|
||||
using Entry = Table::Entry;
|
||||
|
||||
struct Count : public CountBase {
|
||||
Table table;
|
||||
|
||||
explicit Count(CountType& type) : CountBase(type) { }
|
||||
|
||||
bool init() { return table.init(); }
|
||||
};
|
||||
|
||||
CountTypePtr classesType;
|
||||
|
||||
public:
|
||||
explicit ByDomObjectClass(CountTypePtr& classesType)
|
||||
: CountType(),
|
||||
classesType(std::move(classesType))
|
||||
{ }
|
||||
|
||||
void destructCount(CountBase& countBase) override {
|
||||
Count& count = static_cast<Count&>(countBase);
|
||||
count.~Count();
|
||||
}
|
||||
|
||||
CountBasePtr makeCount() override;
|
||||
void traceCount(CountBase& countBase, JSTracer* trc) override;
|
||||
bool count(CountBase& countBase, mozilla::MallocSizeOf mallocSizeOf, const Node& node) override;
|
||||
bool report(JSContext* cx, CountBase& countBase, MutableHandleValue report) override;
|
||||
};
|
||||
|
||||
CountBasePtr
|
||||
ByDomObjectClass::makeCount()
|
||||
{
|
||||
auto count = js::MakeUnique<Count>(*this);
|
||||
if (!count || !count->init())
|
||||
return nullptr;
|
||||
|
||||
return CountBasePtr(count.release());
|
||||
}
|
||||
|
||||
void
|
||||
ByDomObjectClass::traceCount(CountBase& countBase, JSTracer* trc)
|
||||
{
|
||||
Count& count = static_cast<Count&>(countBase);
|
||||
for (Table::Range r = count.table.all(); !r.empty(); r.popFront())
|
||||
r.front().value()->trace(trc);
|
||||
}
|
||||
|
||||
bool
|
||||
ByDomObjectClass::count(CountBase& countBase, mozilla::MallocSizeOf mallocSizeOf, const Node& node)
|
||||
{
|
||||
Count& count = static_cast<Count&>(countBase);
|
||||
|
||||
const char16_t* nodeName = node.descriptiveTypeName();
|
||||
if (!nodeName)
|
||||
return false;
|
||||
|
||||
UniqueC16String name = DuplicateString(nodeName);
|
||||
if (!name)
|
||||
return false;
|
||||
|
||||
Table::AddPtr p = count.table.lookupForAdd(name);
|
||||
if (!p) {
|
||||
CountBasePtr classesCount(classesType->makeCount());
|
||||
if (!classesCount || !count.table.add(p, std::move(name), std::move(classesCount)))
|
||||
return false;
|
||||
}
|
||||
return p->value()->count(mallocSizeOf, node);
|
||||
}
|
||||
|
||||
bool
|
||||
ByDomObjectClass::report(JSContext* cx, CountBase& countBase, MutableHandleValue report)
|
||||
{
|
||||
Count& count = static_cast<Count&>(countBase);
|
||||
|
||||
RootedPlainObject obj(cx, countMap16ToObject(cx, count.table, [](const UniqueC16String& key) {
|
||||
return key.get();
|
||||
}));
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
report.setObject(*obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
// A count type that categorizes nodes by their ubi::Node::typeName.
|
||||
class ByUbinodeType : public CountType {
|
||||
@ -1058,11 +1223,15 @@ ParseBreakdown(JSContext* cx, HandleValue breakdownValue)
|
||||
CountTypePtr otherType(ParseChildBreakdown(cx, breakdown, cx->names().other));
|
||||
if (!otherType)
|
||||
return nullptr;
|
||||
CountTypePtr domNodeType(ParseChildBreakdown(cx, breakdown, cx->names().domNode));
|
||||
if (!domNodeType)
|
||||
return nullptr;
|
||||
|
||||
return CountTypePtr(cx->new_<ByCoarseType>(objectsType,
|
||||
scriptsType,
|
||||
stringsType,
|
||||
otherType));
|
||||
otherType,
|
||||
domNodeType));
|
||||
}
|
||||
|
||||
if (StringEqualsAscii(by, "internalType")) {
|
||||
@ -1073,6 +1242,13 @@ ParseBreakdown(JSContext* cx, HandleValue breakdownValue)
|
||||
return CountTypePtr(cx->new_<ByUbinodeType>(thenType));
|
||||
}
|
||||
|
||||
if (StringEqualsAscii(by, "descriptiveType")) {
|
||||
CountTypePtr thenType(ParseChildBreakdown(cx, breakdown, cx->names().then));
|
||||
if (!thenType)
|
||||
return nullptr;
|
||||
return CountTypePtr(cx->new_<ByDomObjectClass>(thenType));
|
||||
}
|
||||
|
||||
if (StringEqualsAscii(by, "allocationStack")) {
|
||||
CountTypePtr thenType(ParseChildBreakdown(cx, breakdown, cx->names().then));
|
||||
if (!thenType)
|
||||
@ -1114,11 +1290,15 @@ ParseBreakdown(JSContext* cx, HandleValue breakdownValue)
|
||||
//
|
||||
// { by: "coarseType",
|
||||
// objects: { by: "objectClass" },
|
||||
// other: { by: "internalType" }
|
||||
// other: { by: "internalType" },
|
||||
// domNode: { by: "descriptiveType" }
|
||||
// }
|
||||
static CountTypePtr
|
||||
GetDefaultBreakdown(JSContext* cx)
|
||||
{
|
||||
CountTypePtr byDomClass(cx->new_<SimpleCount>());
|
||||
if (!byDomClass)
|
||||
return nullptr;
|
||||
CountTypePtr byClass(cx->new_<SimpleCount>());
|
||||
if (!byClass)
|
||||
return nullptr;
|
||||
@ -1146,11 +1326,15 @@ GetDefaultBreakdown(JSContext* cx)
|
||||
CountTypePtr other(cx->new_<ByUbinodeType>(byType));
|
||||
if (!other)
|
||||
return nullptr;
|
||||
CountTypePtr domNode(cx->new_<ByDomObjectClass>(byDomClass));
|
||||
if (!domNode)
|
||||
return nullptr;
|
||||
|
||||
return CountTypePtr(cx->new_<ByCoarseType>(objects,
|
||||
scripts,
|
||||
strings,
|
||||
other));
|
||||
other,
|
||||
domNode));
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "vm/Xdr.h"
|
||||
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/PodOperations.h"
|
||||
#include "mozilla/ScopeExit.h"
|
||||
|
||||
@ -21,7 +22,7 @@
|
||||
#include "vm/TraceLogging.h"
|
||||
|
||||
using namespace js;
|
||||
using mozilla::PodEqual;
|
||||
using mozilla::ArrayEqual;
|
||||
|
||||
template<XDRMode mode>
|
||||
LifoAlloc&
|
||||
@ -116,7 +117,7 @@ VersionCheck(XDRState<mode>* xdr)
|
||||
MOZ_TRY(xdr->codeBytes(decodedBuildId.begin(), buildIdLength));
|
||||
|
||||
// We do not provide binary compatibility with older scripts.
|
||||
if (!PodEqual(decodedBuildId.begin(), buildId.begin(), buildIdLength))
|
||||
if (!ArrayEqual(decodedBuildId.begin(), buildId.begin(), buildIdLength))
|
||||
return xdr->fail(JS::TranscodeResult_Failure_BadBuildId);
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include "wasm/AsmJS.h"
|
||||
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/Compression.h"
|
||||
#include "mozilla/MathAlgorithms.h"
|
||||
@ -58,6 +59,7 @@ using namespace js::frontend;
|
||||
using namespace js::jit;
|
||||
using namespace js::wasm;
|
||||
|
||||
using mozilla::ArrayEqual;
|
||||
using mozilla::CeilingLog2;
|
||||
using mozilla::Compression::LZ4;
|
||||
using mozilla::HashGeneric;
|
||||
@ -65,7 +67,6 @@ using mozilla::IsNaN;
|
||||
using mozilla::IsNegativeZero;
|
||||
using mozilla::IsPositiveZero;
|
||||
using mozilla::IsPowerOfTwo;
|
||||
using mozilla::PodEqual;
|
||||
using mozilla::PodZero;
|
||||
using mozilla::PositiveInfinity;
|
||||
using mozilla::Unused;
|
||||
@ -6827,7 +6828,7 @@ class ModuleCharsForLookup : ModuleChars
|
||||
MOZ_ASSERT(parseLimit >= parseBegin);
|
||||
if (uint32_t(parseLimit - parseBegin) < chars_.length())
|
||||
return false;
|
||||
if (!PodEqual(chars_.begin(), parseBegin, chars_.length()))
|
||||
if (!ArrayEqual(chars_.begin(), parseBegin, chars_.length()))
|
||||
return false;
|
||||
if (isFunCtor_ != parser.pc->isStandaloneFunctionBody())
|
||||
return false;
|
||||
|
@ -541,7 +541,7 @@ Assumptions::operator==(const Assumptions& rhs) const
|
||||
{
|
||||
return cpuId == rhs.cpuId &&
|
||||
buildId.length() == rhs.buildId.length() &&
|
||||
PodEqual(buildId.begin(), rhs.buildId.begin(), buildId.length());
|
||||
ArrayEqual(buildId.begin(), rhs.buildId.begin(), buildId.length());
|
||||
}
|
||||
|
||||
size_t
|
||||
|
@ -20,6 +20,7 @@
|
||||
#define wasm_types_h
|
||||
|
||||
#include "mozilla/Alignment.h"
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/Atomics.h"
|
||||
#include "mozilla/EnumeratedArray.h"
|
||||
#include "mozilla/HashFunctions.h"
|
||||
@ -75,6 +76,7 @@ typedef Rooted<WasmGlobalObject*> RootedWasmGlobalObject;
|
||||
|
||||
namespace wasm {
|
||||
|
||||
using mozilla::ArrayEqual;
|
||||
using mozilla::Atomic;
|
||||
using mozilla::DebugOnly;
|
||||
using mozilla::EnumeratedArray;
|
||||
@ -83,7 +85,6 @@ using mozilla::MallocSizeOf;
|
||||
using mozilla::Nothing;
|
||||
using mozilla::PodZero;
|
||||
using mozilla::PodCopy;
|
||||
using mozilla::PodEqual;
|
||||
using mozilla::Some;
|
||||
using mozilla::Unused;
|
||||
|
||||
|
@ -8,7 +8,6 @@
|
||||
#define nsCSSPropertyIDSet_h__
|
||||
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/PodOperations.h"
|
||||
|
||||
#include "nsCSSPropertyID.h"
|
||||
#include <limits.h> // for CHAR_BIT
|
||||
@ -64,7 +63,7 @@ public:
|
||||
}
|
||||
|
||||
bool Equals(const nsCSSPropertyIDSet& aOther) const {
|
||||
return mozilla::PodEqual(mProperties, aOther.mProperties);
|
||||
return mozilla::ArrayEqual(mProperties, aOther.mProperties);
|
||||
}
|
||||
|
||||
bool IsEmpty() const {
|
||||
|
@ -436,6 +436,8 @@ TEST(Jemalloc, InPlace)
|
||||
// moz_dispose_arena(arena);
|
||||
}
|
||||
|
||||
// Bug 1474254: disable this test for windows ccov builds because it leads to timeout.
|
||||
#if !defined(XP_WIN) || !defined(MOZ_CODE_COVERAGE)
|
||||
TEST(Jemalloc, JunkPoison)
|
||||
{
|
||||
jemalloc_stats_t stats;
|
||||
@ -622,3 +624,4 @@ TEST(Jemalloc, JunkPoison)
|
||||
// Until Bug 1364359 is fixed it is unsafe to call moz_dispose_arena.
|
||||
// moz_dispose_arena(buf_arena);
|
||||
}
|
||||
#endif
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -98,6 +99,24 @@ ArrayEnd(const Array<T, N>& aArr)
|
||||
return &aArr[0] + ArrayLength(aArr);
|
||||
}
|
||||
|
||||
/**
|
||||
* std::equal has subpar ergonomics.
|
||||
*/
|
||||
|
||||
template<typename T, typename U, size_t N>
|
||||
bool
|
||||
ArrayEqual(const T (&a)[N], const U (&b)[N])
|
||||
{
|
||||
return std::equal(a, a + N, b);
|
||||
}
|
||||
|
||||
template<typename T, typename U>
|
||||
bool
|
||||
ArrayEqual(const T* const a, const U* const b, const size_t n)
|
||||
{
|
||||
return std::equal(a, a + n, b);
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename AlignType, typename Pointee,
|
||||
|
@ -99,6 +99,11 @@ struct LinkedListElementTraits
|
||||
// to a list.
|
||||
static void enterList(LinkedListElement<T>* elt) {}
|
||||
static void exitList(LinkedListElement<T>* elt) {}
|
||||
|
||||
// This method is called when AutoCleanLinkedList cleans itself
|
||||
// during destruction. It can be used to call delete on elements if
|
||||
// the list is the sole owner.
|
||||
static void cleanElement(LinkedListElement<T>* elt) { delete elt->asT(); }
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
@ -111,6 +116,7 @@ struct LinkedListElementTraits<RefPtr<T>>
|
||||
|
||||
static void enterList(LinkedListElement<RefPtr<T>>* elt) { elt->asT()->AddRef(); }
|
||||
static void exitList(LinkedListElement<RefPtr<T>>* elt) { elt->asT()->Release(); }
|
||||
static void cleanElement(LinkedListElement<RefPtr<T>>* elt) {}
|
||||
};
|
||||
|
||||
} /* namespace detail */
|
||||
@ -655,6 +661,9 @@ private:
|
||||
template <typename T>
|
||||
class AutoCleanLinkedList : public LinkedList<T>
|
||||
{
|
||||
private:
|
||||
using Traits = detail::LinkedListElementTraits<T>;
|
||||
using ClientType = typename detail::LinkedListElementTraits<T>::ClientType;
|
||||
public:
|
||||
~AutoCleanLinkedList()
|
||||
{
|
||||
@ -669,8 +678,8 @@ public:
|
||||
|
||||
void clear()
|
||||
{
|
||||
while (T* element = this->popFirst()) {
|
||||
delete element;
|
||||
while (ClientType element = this->popFirst()) {
|
||||
Traits::cleanElement(element);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
@ -158,38 +159,9 @@ PodMove(T* aDst, const T* aSrc, size_t aNElem)
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the |len| elements at |one| are memory-identical to the
|
||||
* |len| elements at |two|.
|
||||
* Looking for a PodEqual? Use ArrayEqual from ArrayUtils.h.
|
||||
* Note that we *cannot* use memcmp for this, due to padding bytes, etc..
|
||||
*/
|
||||
template<typename T>
|
||||
static MOZ_ALWAYS_INLINE bool
|
||||
PodEqual(const T* one, const T* two, size_t len)
|
||||
{
|
||||
if (len < 128) {
|
||||
const T* p1end = one + len;
|
||||
const T* p1 = one;
|
||||
const T* p2 = two;
|
||||
for (; p1 < p1end; p1++, p2++) {
|
||||
if (*p1 != *p2) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return !memcmp(one, two, len * sizeof(T));
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine whether the |N| elements at |one| are memory-identical to the
|
||||
* |N| elements at |two|.
|
||||
*/
|
||||
template <class T, size_t N>
|
||||
static MOZ_ALWAYS_INLINE bool
|
||||
PodEqual(const T (&one)[N], const T (&two)[N])
|
||||
{
|
||||
return PodEqual(one, two, N);
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
|
93
mfbt/tests/gtest/TestLinkedList.cpp
Normal file
93
mfbt/tests/gtest/TestLinkedList.cpp
Normal file
@ -0,0 +1,93 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "mozilla/LinkedList.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
|
||||
using mozilla::AutoCleanLinkedList;
|
||||
using mozilla::LinkedList;
|
||||
using mozilla::LinkedListElement;
|
||||
|
||||
class PtrClass : public LinkedListElement<PtrClass>
|
||||
{
|
||||
public:
|
||||
bool* mResult;
|
||||
|
||||
explicit PtrClass(bool* result)
|
||||
: mResult(result)
|
||||
{
|
||||
EXPECT_TRUE(!*mResult);
|
||||
}
|
||||
|
||||
virtual ~PtrClass() {
|
||||
*mResult = true;
|
||||
}
|
||||
};
|
||||
|
||||
class InheritedPtrClass : public PtrClass {
|
||||
public:
|
||||
bool* mInheritedResult;
|
||||
|
||||
InheritedPtrClass(bool* result, bool* inheritedResult)
|
||||
: PtrClass(result)
|
||||
, mInheritedResult(inheritedResult)
|
||||
{
|
||||
EXPECT_TRUE(!*mInheritedResult);
|
||||
}
|
||||
|
||||
virtual ~InheritedPtrClass() {
|
||||
*mInheritedResult = true;
|
||||
}
|
||||
};
|
||||
|
||||
TEST(LinkedList, AutoCleanLinkedList)
|
||||
{
|
||||
bool rv1 = false;
|
||||
bool rv2 = false;
|
||||
bool rv3 = false;
|
||||
{
|
||||
AutoCleanLinkedList<PtrClass> list;
|
||||
list.insertBack(new PtrClass(&rv1));
|
||||
list.insertBack(new InheritedPtrClass(&rv2, &rv3));
|
||||
}
|
||||
|
||||
EXPECT_TRUE(rv1);
|
||||
EXPECT_TRUE(rv2);
|
||||
EXPECT_TRUE(rv3);
|
||||
}
|
||||
|
||||
class CountedClass final : public LinkedListElement<RefPtr<CountedClass>>
|
||||
{
|
||||
public:
|
||||
int mCount;
|
||||
void AddRef() { mCount++; }
|
||||
void Release() { mCount--; }
|
||||
|
||||
CountedClass()
|
||||
: mCount(0)
|
||||
{
|
||||
}
|
||||
~CountedClass() { EXPECT_TRUE(mCount == 0); }
|
||||
};
|
||||
|
||||
TEST(LinkedList, AutoCleanLinkedListRefPtr)
|
||||
{
|
||||
RefPtr<CountedClass> elt1 = new CountedClass;
|
||||
CountedClass* elt2 = new CountedClass;
|
||||
{
|
||||
AutoCleanLinkedList<RefPtr<CountedClass>> list;
|
||||
list.insertBack(elt1);
|
||||
list.insertBack(elt2);
|
||||
|
||||
EXPECT_TRUE(elt1->mCount == 2);
|
||||
EXPECT_TRUE(elt2->mCount == 1);
|
||||
}
|
||||
|
||||
EXPECT_TRUE(elt1->mCount == 1);
|
||||
EXPECT_TRUE(elt2->mCount == 0);
|
||||
}
|
@ -5,6 +5,7 @@
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'TestLinkedList.cpp',
|
||||
'TestSpan.cpp',
|
||||
]
|
||||
|
||||
|
@ -106,6 +106,13 @@ class AccessibilityTest : BaseSessionTest() {
|
||||
sessionRule.session.accessibility.view = null
|
||||
}
|
||||
|
||||
private fun waitForInitialFocus() {
|
||||
sessionRule.waitUntilCalled(object : EventDelegate {
|
||||
@AssertCalled(count = 1)
|
||||
override fun onFocused(event: AccessibilityEvent) { }
|
||||
})
|
||||
}
|
||||
|
||||
@Test fun testRootNode() {
|
||||
assertThat("provider is not null", provider, notNullValue())
|
||||
val node = provider.createAccessibilityNodeInfo(AccessibilityNodeProvider.HOST_VIEW_ID)
|
||||
@ -125,7 +132,7 @@ class AccessibilityTest : BaseSessionTest() {
|
||||
@Test fun testAccessibilityFocus() {
|
||||
var nodeId = AccessibilityNodeProvider.HOST_VIEW_ID
|
||||
sessionRule.session.loadTestPath(INPUTS_PATH)
|
||||
sessionRule.waitForPageStop()
|
||||
waitForInitialFocus()
|
||||
|
||||
provider.performAction(AccessibilityNodeProvider.HOST_VIEW_ID,
|
||||
AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null)
|
||||
@ -154,7 +161,7 @@ class AccessibilityTest : BaseSessionTest() {
|
||||
|
||||
@Test fun testTextEntryNode() {
|
||||
sessionRule.session.loadString("<input aria-label='Name' value='Tobias'>", "text/html")
|
||||
sessionRule.waitForPageStop()
|
||||
waitForInitialFocus()
|
||||
|
||||
mainSession.evaluateJS("$('input').focus()")
|
||||
|
||||
@ -233,7 +240,7 @@ class AccessibilityTest : BaseSessionTest() {
|
||||
@Test fun testClipboard() {
|
||||
var nodeId = AccessibilityNodeProvider.HOST_VIEW_ID;
|
||||
sessionRule.session.loadString("<input value='hello cruel world' id='input'>", "text/html")
|
||||
sessionRule.waitForPageStop()
|
||||
waitForInitialFocus()
|
||||
|
||||
mainSession.evaluateJS("$('input').focus()")
|
||||
|
||||
@ -284,7 +291,7 @@ class AccessibilityTest : BaseSessionTest() {
|
||||
@Test fun testMoveByCharacter() {
|
||||
var nodeId = AccessibilityNodeProvider.HOST_VIEW_ID
|
||||
sessionRule.session.loadTestPath(LOREM_IPSUM_HTML_PATH)
|
||||
sessionRule.waitForPageStop()
|
||||
waitForInitialFocus()
|
||||
|
||||
provider.performAction(AccessibilityNodeProvider.HOST_VIEW_ID,
|
||||
AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null)
|
||||
@ -317,7 +324,7 @@ class AccessibilityTest : BaseSessionTest() {
|
||||
@Test fun testMoveByWord() {
|
||||
var nodeId = AccessibilityNodeProvider.HOST_VIEW_ID
|
||||
sessionRule.session.loadTestPath(LOREM_IPSUM_HTML_PATH)
|
||||
sessionRule.waitForPageStop()
|
||||
waitForInitialFocus()
|
||||
|
||||
provider.performAction(AccessibilityNodeProvider.HOST_VIEW_ID,
|
||||
AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null)
|
||||
@ -350,7 +357,7 @@ class AccessibilityTest : BaseSessionTest() {
|
||||
@Test fun testMoveByLine() {
|
||||
var nodeId = AccessibilityNodeProvider.HOST_VIEW_ID
|
||||
sessionRule.session.loadTestPath(LOREM_IPSUM_HTML_PATH)
|
||||
sessionRule.waitForPageStop()
|
||||
waitForInitialFocus()
|
||||
|
||||
provider.performAction(AccessibilityNodeProvider.HOST_VIEW_ID,
|
||||
AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null)
|
||||
@ -383,7 +390,7 @@ class AccessibilityTest : BaseSessionTest() {
|
||||
@Test fun testCheckbox() {
|
||||
var nodeId = AccessibilityNodeProvider.HOST_VIEW_ID;
|
||||
sessionRule.session.loadString("<label><input id='checkbox' type='checkbox'>many option</label>", "text/html")
|
||||
sessionRule.waitForPageStop()
|
||||
waitForInitialFocus()
|
||||
|
||||
mainSession.evaluateJS("$('#checkbox').focus()")
|
||||
sessionRule.waitUntilCalled(object : EventDelegate {
|
||||
@ -413,7 +420,7 @@ class AccessibilityTest : BaseSessionTest() {
|
||||
<li id="li" role="option" onclick="this.setAttribute('aria-selected',
|
||||
this.getAttribute('aria-selected') == 'true' ? 'false' : 'true')">1</li>
|
||||
</ul>""","text/html")
|
||||
sessionRule.waitForPageStop()
|
||||
waitForInitialFocus()
|
||||
|
||||
provider.performAction(nodeId, AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null)
|
||||
sessionRule.waitUntilCalled(object : EventDelegate {
|
||||
|
@ -1102,17 +1102,17 @@ CertIsAuthoritativeForEVPolicy(const UniqueCERTCertificate& cert,
|
||||
// This check ensures that only the specific roots we approve for EV get
|
||||
// that status, and not certs (roots or otherwise) that happen to have an
|
||||
// OID that's already been approved for EV.
|
||||
if (!PodEqual(fingerprint, entry.sha256Fingerprint)) {
|
||||
if (!ArrayEqual(fingerprint, entry.sha256Fingerprint)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cabforumOIDData && cabforumOIDData->oid.len == policy.numBytes &&
|
||||
PodEqual(cabforumOIDData->oid.data, policy.bytes, policy.numBytes)) {
|
||||
ArrayEqual(cabforumOIDData->oid.data, policy.bytes, policy.numBytes)) {
|
||||
return true;
|
||||
}
|
||||
const SECOidData* oidData = SECOID_FindOIDByTag(sEVInfoOIDTags[i]);
|
||||
if (oidData && oidData->oid.len == policy.numBytes &&
|
||||
PodEqual(oidData->oid.data, policy.bytes, policy.numBytes)) {
|
||||
ArrayEqual(oidData->oid.data, policy.bytes, policy.numBytes)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -1188,7 +1188,7 @@ LoadExtendedValidationInfo()
|
||||
if (srv != SECSuccess) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
bool same = PodEqual(certFingerprint, entry.sha256Fingerprint);
|
||||
bool same = ArrayEqual(certFingerprint, entry.sha256Fingerprint);
|
||||
MOZ_ASSERT(same, "EV root fingerprint mismatch");
|
||||
if (!same) {
|
||||
return NS_ERROR_FAILURE;
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
#include "nsNSSCertificate.h"
|
||||
#include "nsNSSCertValidity.h"
|
||||
#include "mozilla/PodOperations.h"
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
@ -29,7 +29,7 @@ CertDNIsInList(const CERTCertificate* aCert, const DataAndLength (&aDnList)[T])
|
||||
|
||||
for (auto& dn: aDnList) {
|
||||
if (aCert->derSubject.len == dn.len &&
|
||||
mozilla::PodEqual(aCert->derSubject.data, dn.data, dn.len)) {
|
||||
mozilla::ArrayEqual(aCert->derSubject.data, dn.data, dn.len)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -47,7 +47,7 @@ CertSPKIIsInList(const CERTCertificate* aCert, const DataAndLength (&aSpkiList)[
|
||||
|
||||
for (auto& spki: aSpkiList) {
|
||||
if (aCert->derPublicKey.len == spki.len &&
|
||||
mozilla::PodEqual(aCert->derPublicKey.data, spki.data, spki.len)) {
|
||||
mozilla::ArrayEqual(aCert->derPublicKey.data, spki.data, spki.len)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -64,9 +64,9 @@ CertMatchesStaticData(const CERTCertificate* cert,
|
||||
return false;
|
||||
}
|
||||
return cert->derSubject.len == T &&
|
||||
mozilla::PodEqual(cert->derSubject.data, subject, T) &&
|
||||
mozilla::ArrayEqual(cert->derSubject.data, subject, T) &&
|
||||
cert->derPublicKey.len == R &&
|
||||
mozilla::PodEqual(cert->derPublicKey.data, spki, R);
|
||||
mozilla::ArrayEqual(cert->derPublicKey.data, spki, R);
|
||||
}
|
||||
|
||||
// Implements the graduated Symantec distrust algorithm from Bug 1409257.
|
||||
|
@ -8,8 +8,8 @@
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "md4.h"
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/Casting.h"
|
||||
#include "mozilla/PodOperations.h"
|
||||
|
||||
struct RFC1320TestParams
|
||||
{
|
||||
@ -68,7 +68,7 @@ TEST_P(psm_MD4, RFC1320TestValues)
|
||||
uint8_t actualHash[16];
|
||||
md4sum(mozilla::BitwiseCast<const uint8_t*, const char*>(params.data),
|
||||
strlen(params.data), actualHash);
|
||||
EXPECT_TRUE(mozilla::PodEqual(actualHash, params.expectedHash))
|
||||
EXPECT_TRUE(mozilla::ArrayEqual(actualHash, params.expectedHash))
|
||||
<< "MD4 hashes aren't equal for input: '" << params.data << "'";
|
||||
}
|
||||
|
||||
|
@ -603,7 +603,7 @@ var State = {
|
||||
dispatchesSincePrevious: prev ? dispatches - prev.dispatchCount : NaN,
|
||||
dispatchesSinceStartOfBuffer: oldest ? dispatches - oldest.dispatchCount : NaN,
|
||||
children: tab.children});
|
||||
}).sort((a, b) => b.dispatchesSinceStartOfBuffer - a.dispatchesSinceStartOfBuffer);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@ -954,7 +954,7 @@ var Control = {
|
||||
// Make sure that we do not keep obsolete stuff around.
|
||||
View.DOMCache.trimTo(state.deltas);
|
||||
} else {
|
||||
let counters = State.getCounters();
|
||||
let counters = this._sortCounters(State.getCounters());
|
||||
for (let {name, image, totalDispatches, dispatchesSincePrevious,
|
||||
totalDuration, durationSincePrevious, children} of counters) {
|
||||
function dispatchesAndDuration(dispatches, duration) {
|
||||
@ -995,6 +995,15 @@ var Control = {
|
||||
// Inform watchers
|
||||
Services.obs.notifyObservers(null, UPDATE_COMPLETE_TOPIC, mode);
|
||||
},
|
||||
_sortCounters(counters) {
|
||||
return counters.sort((a, b) => {
|
||||
if (a.dispatchesSinceStartOfBuffer != b.dispatchesSinceStartOfBuffer)
|
||||
return b.dispatchesSinceStartOfBuffer - a.dispatchesSinceStartOfBuffer;
|
||||
if (a.totalDispatches != b.totalDispatches)
|
||||
return b.totalDispatches - a.totalDispatches;
|
||||
return a.name.localeCompare(b.name);
|
||||
});
|
||||
},
|
||||
_setOptions(options) {
|
||||
dump(`about:performance _setOptions ${JSON.stringify(options)}\n`);
|
||||
let eltRefresh = document.getElementById("check-autorefresh");
|
||||
|
@ -1250,6 +1250,7 @@ nsWebBrowser::Create()
|
||||
mDocShell->SetItemType(nsIDocShellTreeItem::typeContent);
|
||||
}
|
||||
mDocShell->SetTreeOwner(mDocShellTreeOwner);
|
||||
mDocShell->AttachBrowsingContext(nullptr);
|
||||
|
||||
// If the webbrowser is a content docshell item then we won't hear any
|
||||
// events from subframes. To solve that we install our own chrome event
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user