Merge m-c to b2ginbound, a=merge

--HG--
extra : commitid : IGU3ThODOFR
This commit is contained in:
Wes Kocher 2015-10-23 15:52:06 -07:00
Родитель 711a677314 efe440fad9
Коммит 2625db041f
262 изменённых файлов: 2979 добавлений и 1343 удалений

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

@ -917,7 +917,7 @@ Swipe.prototype.compile = function Swipe_compile() {
let edge = EDGE * Utils.dpi;
if (Math.abs(deltaX) > Math.abs(deltaY)) {
// Horizontal swipe.
let startPoints = [touch.x1 for (touch of detail.touches)];
let startPoints = detail.touches.map(touch => touch.x1);
if (deltaX > 0) {
detail.type = type + 'right';
detail.edge = Math.min.apply(null, startPoints) <= edge;
@ -928,7 +928,7 @@ Swipe.prototype.compile = function Swipe_compile() {
}
} else {
// Vertical swipe.
let startPoints = [touch.y1 for (touch of detail.touches)];
let startPoints = detail.touches.map(touch => touch.y1);
if (deltaY > 0) {
detail.type = type + 'down';
detail.edge = Math.min.apply(null, startPoints) <= edge;

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

@ -67,11 +67,13 @@ var OutputGenerator = {
if (this.outputOrder === OUTPUT_DESC_FIRST) {
contextStart.forEach(addOutput);
addOutput(aContext.accessible);
[addOutput(node) for // jshint ignore:line
(node of aContext.subtreeGenerator(true, ignoreSubtree))]; // jshint ignore:line
for (let node of aContext.subtreeGenerator(true, ignoreSubtree)) {
addOutput(node);
}
} else {
[addOutput(node) for // jshint ignore:line
(node of aContext.subtreeGenerator(false, ignoreSubtree))]; // jshint ignore:line
for (let node of aContext.subtreeGenerator(false, ignoreSubtree)) {
addOutput(node);
}
addOutput(aContext.accessible);
// If there are any documents in new ancestry, find a first one and place

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

@ -684,7 +684,7 @@ this.Presentation = { // jshint ignore:line
'b2g': [VisualPresenter, B2GPresenter],
'browser': [VisualPresenter, B2GPresenter, AndroidPresenter]
};
this.presenters = [new P() for (P of presenterMap[Utils.MozBuildApp])]; // jshint ignore:line
this.presenters = presenterMap[Utils.MozBuildApp].map(P => new P());
return this.presenters;
},
@ -700,61 +700,58 @@ this.Presentation = { // jshint ignore:line
aPosition, aOldPosition, aStartOffset, aEndOffset);
this.displayedAccessibles.set(context.accessible.document.window, context);
return [p.pivotChanged(context, aReason, aIsUserInput)
for each (p in this.presenters)]; // jshint ignore:line
return this.presenters.map(p => p.pivotChanged(context, aReason, aIsUserInput));
},
actionInvoked: function Presentation_actionInvoked(aObject, aActionName) {
return [p.actionInvoked(aObject, aActionName) // jshint ignore:line
for each (p in this.presenters)]; // jshint ignore:line
return this.presenters.map(p => p.actionInvoked(aObject, aActionName));
},
textChanged: function Presentation_textChanged(aAccessible, aIsInserted,
aStartOffset, aLength, aText,
aModifiedText) {
return [p.textChanged(aAccessible, aIsInserted, aStartOffset, aLength, // jshint ignore:line
aText, aModifiedText) for each (p in this.presenters)]; // jshint ignore:line
return this.presenters.map(p => p.textChanged(aAccessible, aIsInserted,
aStartOffset, aLength,
aText, aModifiedText));
},
textSelectionChanged: function textSelectionChanged(aText, aStart, aEnd,
aOldStart, aOldEnd,
aIsFromUserInput) {
return [p.textSelectionChanged(aText, aStart, aEnd, aOldStart, aOldEnd, // jshint ignore:line
aIsFromUserInput) for each (p in this.presenters)]; // jshint ignore:line
return this.presenters.map(p => p.textSelectionChanged(aText, aStart, aEnd,
aOldStart, aOldEnd,
aIsFromUserInput));
},
nameChanged: function nameChanged(aAccessible) {
return [ p.nameChanged(aAccessible) for (p of this.presenters) ]; // jshint ignore:line
return this.presenters.map(p => p.nameChanged(aAccessible));
},
valueChanged: function valueChanged(aAccessible) {
return [ p.valueChanged(aAccessible) for (p of this.presenters) ]; // jshint ignore:line
return this.presenters.map(p => p.valueChanged(aAccessible));
},
tabStateChanged: function Presentation_tabStateChanged(aDocObj, aPageState) {
return [p.tabStateChanged(aDocObj, aPageState) // jshint ignore:line
for each (p in this.presenters)]; // jshint ignore:line
return this.presenters.map(p => p.tabStateChanged(aDocObj, aPageState));
},
viewportChanged: function Presentation_viewportChanged(aWindow) {
let context = this.displayedAccessibles.get(aWindow);
return [p.viewportChanged(aWindow, context) // jshint ignore:line
for each (p in this.presenters)]; // jshint ignore:line
return this.presenters.map(p => p.viewportChanged(aWindow, context));
},
editingModeChanged: function Presentation_editingModeChanged(aIsEditing) {
return [p.editingModeChanged(aIsEditing) for each (p in this.presenters)]; // jshint ignore:line
return this.presenters.map(p => p.editingModeChanged(aIsEditing));
},
announce: function Presentation_announce(aAnnouncement) {
// XXX: Typically each presenter uses the UtteranceGenerator,
// but there really isn't a point here.
return [p.announce(UtteranceGenerator.genForAnnouncement(aAnnouncement)) // jshint ignore:line
for each (p in this.presenters)]; // jshint ignore:line
return this.presenters.map(p => p.announce(UtteranceGenerator.genForAnnouncement(aAnnouncement)));
},
noMove: function Presentation_noMove(aMoveMethod) {
return [p.noMove(aMoveMethod) for each (p in this.presenters)]; // jshint ignore:line
return this.presenters.map(p => p.noMove(aMoveMethod));
},
liveRegion: function Presentation_liveRegion(aAccessible, aIsPolite, aIsHide,
@ -764,7 +761,7 @@ this.Presentation = { // jshint ignore:line
context = new PivotContext(aAccessible, null, -1, -1, true,
aIsHide ? true : false);
}
return [p.liveRegion(context, aIsPolite, aIsHide, aModifiedText) // jshint ignore:line
for (p of this.presenters)]; // jshint ignore:line
return this.presenters.map(p => p.liveRegion(context, aIsPolite, aIsHide,
aModifiedText));
}
};

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

@ -211,11 +211,10 @@ this.Utils = { // jshint ignore:line
localize: function localize(aOutput) {
let outputArray = Array.isArray(aOutput) ? aOutput : [aOutput];
let localized =
[this.stringBundle.get(details) for (details of outputArray)]; // jshint ignore:line
outputArray.map(details => this.stringBundle.get(details));
// Clean up the white space.
let trimmed;
return [trimmed for (word of localized) if (word && // jshint ignore:line
(trimmed = word.trim()))]; // jshint ignore:line
return localized.filter(word => word).map(word => word.trim()).
filter(trimmed => trimmed);
},
get stringBundle() {
@ -834,9 +833,9 @@ PivotContext.prototype = {
*/
get newAncestry() {
if (!this._newAncestry) {
this._newAncestry = this._ignoreAncestry ? [] : [currentAncestor for ( // jshint ignore:line
[index, currentAncestor] of Iterator(this.currentAncestry)) if ( // jshint ignore:line
currentAncestor !== this.oldAncestry[index])]; // jshint ignore:line
this._newAncestry = this._ignoreAncestry ? [] :
this.currentAncestry.filter(
(currentAncestor, i) => currentAncestor !== this.oldAncestry[i]);
}
return this._newAncestry;
},
@ -862,9 +861,13 @@ PivotContext.prototype = {
if (include) {
if (aPreorder) {
yield child;
[yield node for (node of this._traverse(child, aPreorder, aStop))]; // jshint ignore:line
for (let node of this._traverse(child, aPreorder, aStop)) {
yield node;
}
} else {
[yield node for (node of this._traverse(child, aPreorder, aStop))]; // jshint ignore:line
for (let node of this._traverse(child, aPreorder, aStop)) {
yield node;
}
yield child;
}
}
@ -986,15 +989,13 @@ PivotContext.prototype = {
cellInfo.columnHeaders = [];
if (cellInfo.columnChanged && cellInfo.current.role !==
Roles.COLUMNHEADER) {
cellInfo.columnHeaders = [headers for (headers of getHeaders( // jshint ignore:line
cellInfo.current.columnHeaderCells))];
cellInfo.columnHeaders = [...getHeaders(cellInfo.current.columnHeaderCells)];
}
cellInfo.rowHeaders = [];
if (cellInfo.rowChanged &&
(cellInfo.current.role === Roles.CELL ||
cellInfo.current.role === Roles.MATHML_CELL)) {
cellInfo.rowHeaders = [headers for (headers of getHeaders( // jshint ignore:line
cellInfo.current.rowHeaderCells))];
cellInfo.rowHeaders = [...getHeaders(cellInfo.current.rowHeaderCells)];
}
this._cells.set(domNode, cellInfo);

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

@ -166,7 +166,7 @@ var AccessFuTest = {
AccessFuTest.nextTest();
} else {
// Run all test functions synchronously.
[testFunc() for (testFunc of gTestFuncs)]; // jshint ignore:line
gTestFuncs.forEach(testFunc => testFunc());
AccessFuTest.finish();
}
});

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

@ -65,7 +65,7 @@
}
},
action: function action() {
[hide(id) for (id of ["to_hide1", "to_hide2", "to_hide3", "to_hide4"])];
["to_hide1", "to_hide2", "to_hide3", "to_hide4"].forEach(id => hide(id));
}
}, {
expected: {
@ -76,8 +76,8 @@
}
},
action: function action() {
[hide(id) for (id of ["to_hide_descendant1", "to_hide_descendant2",
"to_hide_descendant3", "to_hide_descendant4"])];
["to_hide_descendant1", "to_hide_descendant2",
"to_hide_descendant3", "to_hide_descendant4"].forEach(id => hide(id));
}
}, {
expected: {
@ -88,7 +88,7 @@
}
},
action: function action() {
[show(id) for (id of ["to_show1", "to_show2", "to_show3", "to_show4"])];
["to_show1", "to_show2", "to_show3", "to_show4"].forEach(id => show(id));
}
}, {
expected: {
@ -99,8 +99,8 @@
}
},
action: function action() {
[show(id) for (id of ["to_show_descendant1", "to_show_descendant2",
"to_show_descendant3", "to_show_descendant4"])];
["to_show_descendant1", "to_show_descendant2",
"to_show_descendant3", "to_show_descendant4"].forEach(id => show(id));
}
}, {
expected: {
@ -111,8 +111,7 @@
}
},
action: function action() {
[ariaHide(id) for (id of ["to_hide5", "to_hide6", "to_hide7",
"to_hide8", "to_hide9"])];
["to_hide5", "to_hide6", "to_hide7", "to_hide8", "to_hide9"].forEach(id => ariaHide(id));
}
}, {
expected: {
@ -123,8 +122,8 @@
}
},
action: function action() {
[ariaHide(id) for (id of ["to_hide_descendant5", "to_hide_descendant6",
"to_hide_descendant7", "to_hide_descendant8"])];
["to_hide_descendant5", "to_hide_descendant6",
"to_hide_descendant7", "to_hide_descendant8"].forEach(id => ariaHide(id));
}
}, {
expected: {
@ -135,8 +134,7 @@
}
},
action: function action() {
[ariaShow(id) for (id of ["to_show5", "to_show6", "to_show7",
"to_show8", "to_show9"])];
["to_show5", "to_show6", "to_show7", "to_show8", "to_show9"].forEach(id => ariaShow(id));
}
}, {
expected: {
@ -147,8 +145,8 @@
}
},
action: function action() {
[ariaShow(id) for (id of ["to_show_descendant5", "to_show_descendant6",
"to_show_descendant7", "to_show_descendant8"])];
["to_show_descendant5", "to_show_descendant6",
"to_show_descendant7", "to_show_descendant8"].forEach(id => ariaShow(id));
}
}, {
expected: {
@ -181,7 +179,7 @@
}
},
action: function action() {
[show(id) for (id of ["to_show_live_off", "to_show_live_assertive"])];
["to_show_live_off", "to_show_live_assertive"].forEach(id => show(id));
}
}, {
expected: {
@ -192,8 +190,7 @@
}
},
action: function action() {
[ariaShow(id) for (id of ["to_show_live_off2",
"to_show_live_assertive2"])];
["to_show_live_off2", "to_show_live_assertive2"].forEach(id => ariaShow(id));
}
}, {
expected: {
@ -472,4 +469,4 @@
</div>
</div>
</body>
</html>
</html>

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

@ -12,5 +12,4 @@ if CONFIG['MOZ_EXTENSIONS']:
DIRS += [
'/%s' % CONFIG['MOZ_BRANDING_DIRECTORY'],
'/b2g',
'/devtools',
]

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

@ -0,0 +1,16 @@
[
{
"size": 80458572,
"digest": "e5101f9dee1e462f6cbd3897ea57eede41d23981825c7b20d91d23ab461875d54d3dfc24999aa58a31e8b01f49fb3140e05ffe5af2957ef1d1afb89fd0dfe1ad",
"algorithm": "sha512",
"filename": "gcc.tar.xz",
"unpack": true
},
{
"size": 12057960,
"digest": "6105d6432943141cffb40020dc5ba3a793650bdeb3af9bd5e56d3796c5f03df9962a73e521646cd71fbfb5e266c1e74716ad722fb6055589dfb7d35175bca89e",
"algorithm": "sha512",
"filename": "gtk3.tar.xz",
"unpack": true
}
]

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

@ -0,0 +1,16 @@
[
{
"size": 80458572,
"digest": "e5101f9dee1e462f6cbd3897ea57eede41d23981825c7b20d91d23ab461875d54d3dfc24999aa58a31e8b01f49fb3140e05ffe5af2957ef1d1afb89fd0dfe1ad",
"algorithm": "sha512",
"filename": "gcc.tar.xz",
"unpack": true
},
{
"size": 12057960,
"digest": "6105d6432943141cffb40020dc5ba3a793650bdeb3af9bd5e56d3796c5f03df9962a73e521646cd71fbfb5e266c1e74716ad722fb6055589dfb7d35175bca89e",
"algorithm": "sha512",
"filename": "gtk3.tar.xz",
"unpack": true
}
]

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

@ -39,7 +39,7 @@
},
"b2g_manifest": "aries.xml",
"b2g_manifest_intree": true,
"additional_source_tarballs": ["backup-aries.tar.xz"],
"additional_source_tarballs": [],
"gecko_l10n_root": "https://hg.mozilla.org/l10n-central",
"gaia": {
"l10n": {

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

@ -1,16 +1,16 @@
[
{
"size": 135359412,
"digest": "45e677c9606cc4eec44ef4761df47ff431df1ffad17a5c6d21ce700a1c47f79e87a4aa9f30ae47ff060bd64f5b775d995780d88211f9a759ffa0d076beb4816b",
"algorithm": "sha512",
"filename": "backup-aries.tar.xz",
"comment": "v18D"
},
{
"size": 80458572,
"digest": "e5101f9dee1e462f6cbd3897ea57eede41d23981825c7b20d91d23ab461875d54d3dfc24999aa58a31e8b01f49fb3140e05ffe5af2957ef1d1afb89fd0dfe1ad",
"algorithm": "sha512",
"filename": "gcc.tar.xz",
"unpack": "True"
},
{
"size": 12057960,
"digest": "6105d6432943141cffb40020dc5ba3a793650bdeb3af9bd5e56d3796c5f03df9962a73e521646cd71fbfb5e266c1e74716ad722fb6055589dfb7d35175bca89e",
"algorithm": "sha512",
"filename": "gtk3.tar.xz",
"unpack": true
}
]

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

@ -0,0 +1,16 @@
[
{
"size": 80458572,
"digest": "e5101f9dee1e462f6cbd3897ea57eede41d23981825c7b20d91d23ab461875d54d3dfc24999aa58a31e8b01f49fb3140e05ffe5af2957ef1d1afb89fd0dfe1ad",
"algorithm": "sha512",
"filename": "gcc.tar.xz",
"unpack": true
},
{
"size": 12057960,
"digest": "6105d6432943141cffb40020dc5ba3a793650bdeb3af9bd5e56d3796c5f03df9962a73e521646cd71fbfb5e266c1e74716ad722fb6055589dfb7d35175bca89e",
"algorithm": "sha512",
"filename": "gtk3.tar.xz",
"unpack": true
}
]

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

@ -5,5 +5,12 @@
"algorithm": "sha512",
"filename": "gcc.tar.xz",
"unpack": "True"
},
{
"size": 12057960,
"digest": "6105d6432943141cffb40020dc5ba3a793650bdeb3af9bd5e56d3796c5f03df9962a73e521646cd71fbfb5e266c1e74716ad722fb6055589dfb7d35175bca89e",
"algorithm": "sha512",
"filename": "gtk3.tar.xz",
"unpack": true
}
]

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

@ -0,0 +1,16 @@
[
{
"size": 80458572,
"digest": "e5101f9dee1e462f6cbd3897ea57eede41d23981825c7b20d91d23ab461875d54d3dfc24999aa58a31e8b01f49fb3140e05ffe5af2957ef1d1afb89fd0dfe1ad",
"algorithm": "sha512",
"filename": "gcc.tar.xz",
"unpack": true
},
{
"size": 12057960,
"digest": "6105d6432943141cffb40020dc5ba3a793650bdeb3af9bd5e56d3796c5f03df9962a73e521646cd71fbfb5e266c1e74716ad722fb6055589dfb7d35175bca89e",
"algorithm": "sha512",
"filename": "gtk3.tar.xz",
"unpack": true
}
]

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

@ -12,5 +12,12 @@
"algorithm": "sha512",
"filename": "gcc.tar.xz",
"unpack": "True"
},
{
"size": 12057960,
"digest": "6105d6432943141cffb40020dc5ba3a793650bdeb3af9bd5e56d3796c5f03df9962a73e521646cd71fbfb5e266c1e74716ad722fb6055589dfb7d35175bca89e",
"algorithm": "sha512",
"filename": "gtk3.tar.xz",
"unpack": true
}
]

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

@ -10,5 +10,12 @@
"algorithm": "sha512",
"filename": "gcc.tar.xz",
"unpack": "True"
},
{
"size": 12057960,
"digest": "6105d6432943141cffb40020dc5ba3a793650bdeb3af9bd5e56d3796c5f03df9962a73e521646cd71fbfb5e266c1e74716ad722fb6055589dfb7d35175bca89e",
"algorithm": "sha512",
"filename": "gtk3.tar.xz",
"unpack": true
}
]

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

@ -23,6 +23,13 @@
"algorithm": "sha512",
"filename": "gcc.tar.xz",
"unpack": "True"
},
{
"size": 12057960,
"digest": "6105d6432943141cffb40020dc5ba3a793650bdeb3af9bd5e56d3796c5f03df9962a73e521646cd71fbfb5e266c1e74716ad722fb6055589dfb7d35175bca89e",
"algorithm": "sha512",
"filename": "gtk3.tar.xz",
"unpack": true
}
]

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

@ -23,6 +23,13 @@
"algorithm": "sha512",
"filename": "gcc.tar.xz",
"unpack": "True"
},
{
"size": 12057960,
"digest": "6105d6432943141cffb40020dc5ba3a793650bdeb3af9bd5e56d3796c5f03df9962a73e521646cd71fbfb5e266c1e74716ad722fb6055589dfb7d35175bca89e",
"algorithm": "sha512",
"filename": "gtk3.tar.xz",
"unpack": true
}
]

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

@ -4,4 +4,12 @@
"algorithm": "sha512",
"filename": "gcc.tar.xz",
"unpack": "True"
}]
},
{
"size": 12057960,
"digest": "6105d6432943141cffb40020dc5ba3a793650bdeb3af9bd5e56d3796c5f03df9962a73e521646cd71fbfb5e266c1e74716ad722fb6055589dfb7d35175bca89e",
"algorithm": "sha512",
"filename": "gtk3.tar.xz",
"unpack": true
}
]

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

@ -11,7 +11,6 @@ if CONFIG['MOZ_EXTENSIONS']:
DIRS += [
'/%s' % CONFIG['MOZ_BRANDING_DIRECTORY'],
'/b2g',
'/devtools',
]
# Add the defaults settings.

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

@ -93,7 +93,7 @@
<binding id="notification" extends="chrome://global/content/bindings/notification.xml#notification">
<content>
<xul:hbox class="notification-inner outset" flex="1" xbl:inherits="type">
<xul:hbox class="notification-inner" flex="1" xbl:inherits="type">
<xul:toolbarbutton ondblclick="event.stopPropagation();"
class="messageCloseButton close-icon tabbable"
xbl:inherits="hidden=hideclose"

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

@ -19,7 +19,7 @@
<stylesheet src="chrome://global/skin/notification.css"/>
</resources>
<content>
<xul:hbox class="notification-inner outset" flex="1" xbl:inherits="type">
<xul:hbox class="notification-inner" flex="1" xbl:inherits="type">
<xul:hbox anonid="details" align="center" flex="1">
<xul:image class="translate-infobar-element messageImage"
anonid="messageImage"/>

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

@ -93,6 +93,11 @@ reflow.messageLinkText=function %1$S, %2$S line %3$S
# anonymous. Test console.trace() in the webconsole.
stacktrace.anonymousFunction=<anonymous>
# LOCALIZATION NOTE (stacktrace.asyncStack): this string is used to
# indicate that a given stack frame has an async parent.
# %S is the "Async Cause" of the frame.
stacktrace.asyncStack=(Async: %S)
# LOCALIZATION NOTE (unknownLocation): this string is used to
# display messages with sources that have an unknown location, eg. from
# console.trace() calls.

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

@ -17,7 +17,6 @@ DIRS += [
'modules',
'themes',
'extensions',
'/devtools',
]
DIRS += [

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

@ -311,7 +311,10 @@ var DebuggerView = {
if (button == 2) {
this.clickedLine = line;
}
else {
// Bug 1201008: Only add the breakpoint to the editor if we're currently
// looking at a source. Even if no source is loaded, you can
// interact with line 1 of the editor.
else if (DebuggerView.Sources.selectedValue) {
if (this.editor.hasBreakpoint(line)) {
this.editor.removeBreakpoint(line);
} else {

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

@ -289,6 +289,8 @@ skip-if = e10s # TODO
skip-if = e10s # TODO
[browser_dbg_navigation.js]
skip-if = e10s && debug
[browser_dbg_no-dangling-breakpoints.js]
skip-if = e10s && debug
[browser_dbg_no-page-sources.js]
skip-if = e10s && debug
[browser_dbg_on-pause-highlight.js]

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

@ -0,0 +1,23 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Bug 1201008 - Make sure you can't set a breakpoint in a blank
* editor
*/
function test() {
initDebugger('data:text/html,hi').then(([aTab,, aPanel]) => {
const gPanel = aPanel;
const gDebugger = gPanel.panelWin;
Task.spawn(function*() {
const editor = gDebugger.DebuggerView.editor;
editor.emit("gutterClick", 0);
is(editor.getBreakpoints().length, 0,
"A breakpoint should not exist");
closeDebuggerAndFinish(gPanel);
});
});
}

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

@ -577,10 +577,10 @@ MarkupView.prototype = {
}
break;
case Ci.nsIDOMKeyEvent.DOM_VK_DELETE:
this.deleteNode(this._selectedContainer.node);
this.deleteNodeOrAttribute();
break;
case Ci.nsIDOMKeyEvent.DOM_VK_BACK_SPACE:
this.deleteNode(this._selectedContainer.node, true);
this.deleteNodeOrAttribute(true);
break;
case Ci.nsIDOMKeyEvent.DOM_VK_HOME:
let rootContainer = this.getContainer(this._rootNode);
@ -677,13 +677,32 @@ MarkupView.prototype = {
return name === "input" || name === "textarea";
},
/**
* If there's an attribute on the current node that's currently focused, then
* delete this attribute, otherwise delete the node itself.
* @param {boolean} moveBackward If set to true and if we're deleting the
* node, focus the previous sibling after deletion, otherwise the next one.
*/
deleteNodeOrAttribute: function(moveBackward) {
let focusedAttribute = this.doc.activeElement
? this.doc.activeElement.closest(".attreditor")
: null;
if (focusedAttribute) {
// The focused attribute might not be in the current selected container.
let container = focusedAttribute.closest("li.child").container;
container.removeAttribute(focusedAttribute.dataset.attr);
} else {
this.deleteNode(this._selectedContainer.node, moveBackward);
}
},
/**
* Delete a node from the DOM.
* This is an undoable action.
*
* @param {NodeFront} aNode The node to remove.
* @param {boolean} moveBackward If set to true, focus the previous sibling,
* otherwise the next one.
* otherwise the next one.
*/
deleteNode: function(aNode, moveBackward) {
if (aNode.isDocumentElement ||

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

@ -93,6 +93,7 @@ skip-if = e10s # Bug 1040751 - CodeMirror editor.destroy() isn't e10s compatible
[browser_markupview_keybindings_02.js]
[browser_markupview_keybindings_03.js]
[browser_markupview_keybindings_04.js]
[browser_markupview_keybindings_delete_attributes.js]
[browser_markupview_mutation_01.js]
[browser_markupview_mutation_02.js]
[browser_markupview_navigation.js]

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

@ -0,0 +1,63 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Tests that attributes can be deleted from the markup-view with the delete key
// when they are focused.
const HTML = `<div id="id" class="class" data-id="id"></div>`;
const TEST_URL = "data:text/html;charset=utf-8," + encodeURIComponent(HTML);
// List of all the test cases. Each item is an object with the following props:
// - selector: the css selector of the node that should be selected
// - attribute: the name of the attribute that should be focused. Do not
// specify an attribute that would make it impossible to find the node using
// selector.
// Note that after each test case, undo is called.
const TEST_DATA = [{
selector: "#id",
attribute: "class"
}, {
selector: "#id",
attribute: "data-id"
}];
add_task(function*() {
let {inspector} = yield addTab(TEST_URL).then(openInspector);
let {walker} = inspector;
for (let {selector, attribute} of TEST_DATA) {
info("Get the container for node " + selector);
let {editor} = yield getContainerForSelector(selector, inspector);
info("Focus attribute " + attribute);
let attr = editor.attrElements.get(attribute).querySelector(".editable");
attr.focus();
info("Delete the attribute by pressing delete");
let mutated = inspector.once("markupmutation");
EventUtils.sendKey("delete", inspector.panelWin);
yield mutated;
info("Check that the node is still here");
let node = yield walker.querySelector(walker.rootNode, selector);
ok(node, "The node hasn't been deleted");
info("Check that the attribute has been deleted");
node = yield walker.querySelector(walker.rootNode,
selector + "[" + attribute + "]");
ok(!node, "The attribute does not exist anymore in the DOM");
ok(!editor.attrElements.get(attribute),
"The attribute has been removed from the container");
info("Undo the change");
yield undoChange(inspector);
node = yield walker.querySelector(walker.rootNode,
selector + "[" + attribute + "]");
ok(node, "The attribute is back in the DOM");
ok(editor.attrElements.get(attribute),
"The attribute is back on the container");
}
});

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

@ -8,52 +8,98 @@
// Also checks that after deletion the correct element is highlighted.
// The next sibling is preferred, but the parent is a fallback.
const TEST_URL = "data:text/html,<div id='parent'><div id='first'></div><div id='second'></div><div id='third'></div></div>";
const HTML = `<div id="parent">
<div id="first"></div>
<div id="second"></div>
<div id="third"></div>
</div>`;
const TEST_URL = "data:text/html;charset=utf-8," + encodeURIComponent(HTML);
function* checkDeleteAndSelection(inspector, key, nodeSelector, focusedNodeSelector) {
yield selectNode(nodeSelector, inspector);
yield clickContainer(nodeSelector, inspector);
info(`Deleting the element "${nodeSelector}" using the ${key} key`);
let mutated = inspector.once("markupmutation");
EventUtils.sendKey(key, inspector.panelWin);
yield Promise.all([mutated, inspector.once("inspector-updated")]);
let nodeFront = yield getNodeFront(focusedNodeSelector, inspector);
is(inspector.selection.nodeFront, nodeFront,
focusedNodeSelector + " should be selected after " + nodeSelector + " node gets deleted.");
info("Checking that it's gone, baby gone!");
ok(!content.document.querySelector(nodeSelector), "The test node does not exist");
yield undoChange(inspector);
ok(content.document.querySelector(nodeSelector), "The test node is back!");
}
// List of all the test cases. Each item is an object with the following props:
// - selector: the css selector of the node that should be selected
// - key: the key to press to delete the node (delete or back_space)
// - focusedSelector: the css selector of the node we expect to be selected as
// a result of the deletion
// - setup: an optional function that will be run before selecting and deleting
// the node
// Note that after each test case, undo is called.
const TEST_DATA = [{
selector: "#first",
key: "delete",
focusedSelector: "#second"
}, {
selector: "#second",
key: "delete",
focusedSelector: "#third"
}, {
selector: "#third",
key: "delete",
focusedSelector: "#second"
}, {
selector: "#first",
key: "back_space",
focusedSelector: "#second"
}, {
selector: "#second",
key: "back_space",
focusedSelector: "#first"
}, {
selector: "#third",
key: "back_space",
focusedSelector: "#second"
}, {
setup: function*(inspector) {
// Removing the siblings of #first in order to test with an only child.
let mutated = inspector.once("markupmutation");
for (let node of content.document.querySelectorAll("#second, #third")) {
node.remove();
}
yield mutated;
},
selector: "#first",
key: "delete",
focusedSelector: "#parent"
}, {
selector: "#first",
key: "back_space",
focusedSelector: "#parent"
}];
add_task(function*() {
let {inspector} = yield addTab(TEST_URL).then(openInspector);
info("Selecting the test node by clicking on it to make sure it receives focus");
for (let {setup, selector, key, focusedSelector} of TEST_DATA) {
if (setup) {
yield setup(inspector);
}
yield checkDeleteAndSelection(inspector, "delete", "#first", "#second");
yield checkDeleteAndSelection(inspector, "delete", "#second", "#third");
yield checkDeleteAndSelection(inspector, "delete", "#third", "#second");
yield checkDeleteAndSelection(inspector, "back_space", "#first", "#second");
yield checkDeleteAndSelection(inspector, "back_space", "#second", "#first");
yield checkDeleteAndSelection(inspector, "back_space", "#third", "#second");
// Removing the siblings of #first.
let mutated = inspector.once("markupmutation");
for (let node of content.document.querySelectorAll("#second, #third")) {
node.remove();
yield checkDeleteAndSelection(inspector, key, selector, focusedSelector);
}
yield mutated;
// Testing with an only child.
info("testing with an only child");
yield checkDeleteAndSelection(inspector, "delete", "#first", "#parent");
yield checkDeleteAndSelection(inspector, "back_space", "#first", "#parent");
yield inspector.once("inspector-updated");
});
function* checkDeleteAndSelection(inspector, key, selector, focusedSelector) {
info("Test deleting node " + selector + " with " + key + ", " +
"expecting " + focusedSelector + " to be focused");
info("Select node " + selector + " and make sure it is focused");
yield selectNode(selector, inspector);
yield clickContainer(selector, inspector);
info("Delete the node with: " + key);
let mutated = inspector.once("markupmutation");
EventUtils.sendKey(key, inspector.panelWin);
yield Promise.all([mutated, inspector.once("inspector-updated")]);
let nodeFront = yield getNodeFront(focusedSelector, inspector);
is(inspector.selection.nodeFront, nodeFront,
focusedSelector + " is selected after deletion");
info("Check that the node was really removed");
let node = yield getNodeFront(selector, inspector);
ok(!node, "The node can't be found in the page anymore");
info("Undo the deletion to restore the original markup");
yield undoChange(inspector);
node = yield getNodeFront(selector, inspector);
ok(node, "The node is back");
}

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

@ -3529,8 +3529,10 @@ Widgets.Stacktrace.prototype = Heritage.extend(Widgets.BaseWidget.prototype,
let result = this.element = this.document.createElementNS(XHTML_NS, "ul");
result.className = "stacktrace devtools-monospace";
for (let frame of this.stacktrace) {
result.appendChild(this._renderFrame(frame));
if (this.stacktrace) {
for (let frame of this.stacktrace) {
result.appendChild(this._renderFrame(frame));
}
}
return this;
@ -3549,15 +3551,22 @@ Widgets.Stacktrace.prototype = Heritage.extend(Widgets.BaseWidget.prototype,
{
let fn = this.document.createElementNS(XHTML_NS, "span");
fn.className = "function";
let asyncCause = "";
if (frame.asyncCause) {
asyncCause =
l10n.getFormatStr("stacktrace.asyncStack", [frame.asyncCause]) + " ";
}
if (frame.functionName) {
let span = this.document.createElementNS(XHTML_NS, "span");
span.className = "cm-variable";
span.textContent = frame.functionName;
span.textContent = asyncCause + frame.functionName;
fn.appendChild(span);
fn.appendChild(this.document.createTextNode("()"));
} else {
fn.classList.add("cm-comment");
fn.textContent = l10n.getStr("stacktrace.anonymousFunction");
fn.textContent = asyncCause + l10n.getStr("stacktrace.anonymousFunction");
}
let location = this.output.owner.createLocationNode({url: frame.filename,

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

@ -85,6 +85,7 @@ support-files =
test-console-output-regexp.html
test-console-column.html
test-consoleiframes.html
test-console-trace-async.html
test-certificate-messages.html
test-data.json
test-data.json^headers^
@ -312,6 +313,7 @@ skip-if = e10s # Bug 1042253 - webconsole tests disabled with e10s
[browser_webconsole_console_extras.js]
[browser_webconsole_console_logging_api.js]
[browser_webconsole_console_logging_workers_api.js]
[browser_webconsole_console_trace_async.js]
[browser_webconsole_count.js]
[browser_webconsole_dont_navigate_on_doubleclick.js]
[browser_webconsole_execution_scope.js]

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

@ -0,0 +1,75 @@
/* vim:set ts=2 sw=2 sts=2 et: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const TEST_URI = "http://example.com/browser/devtools/client/" +
"webconsole/test/test-console-trace-async.html";
add_task(function* runTest() {
// Async stacks aren't on by default in all builds
yield new Promise(resolve => {
SpecialPowers.pushPrefEnv({"set": [
["javascript.options.asyncstack", true]
]}, resolve);
});
let {tab} = yield loadTab("data:text/html;charset=utf8,<p>hello");
let hud = yield openConsole(tab);
BrowserTestUtils.loadURI(gBrowser.selectedBrowser, TEST_URI);
let [result] = yield waitForMessages({
webconsole: hud,
messages: [{
name: "console.trace output",
consoleTrace: {
file: "test-console-trace-async.html",
fn: "inner",
},
}],
});
let node = [...result.matched][0];
ok(node, "found trace log node");
ok(node.textContent.includes("console.trace()"),
"trace log node includes console.trace()");
ok(node.textContent.includes("promise callback"),
"trace log node includes promise callback");
ok(node.textContent.includes("setTimeout handler"),
"trace log node includes setTimeout handler");
// The expected stack trace object.
let stacktrace = [
{
columnNumber: 3,
filename: TEST_URI,
functionName: "inner",
language: 2,
lineNumber: 9
},
{
asyncCause: "promise callback",
columnNumber: 1,
filename: TEST_URI,
functionName: "time1",
language: 2,
lineNumber: 13,
},
{
asyncCause: "setTimeout handler",
columnNumber: 1,
filename: TEST_URI,
functionName: "",
language: 2,
lineNumber: 18,
}
];
let obj = node._messageObject;
ok(obj, "console.trace message object");
ok(obj._stacktrace, "found stacktrace object");
is(obj._stacktrace.toSource(), stacktrace.toSource(),
"stacktrace is correct");
});

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

@ -0,0 +1,24 @@
<!DOCTYPE html>
<html lang="en">
<head><meta charset="utf-8">
<title>Web Console test for bug 1200832 - console.trace() async stacks</title>
<!-- Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ -->
<script type="application/javascript">
function inner() {
console.trace();
}
function time1() {
new Promise(function(resolve, reject) {
setTimeout(resolve, 10);
}).then(inner);
}
setTimeout(time1, 10);
</script>
</head>
<body>
<p>Web Console test for bug 1200832 - console.trace() async stacks</p>
</body>
</html>

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

@ -4,13 +4,22 @@
# 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/.
if CONFIG['MOZ_DEVTOOLS'] and CONFIG['MOZ_DEVTOOLS'] not in ('all', 'server'):
error('Unsupported MOZ_DEVTOOLS value: %s' % (CONFIG['MOZ_DEVTOOLS']))
if CONFIG['MOZ_DEVTOOLS'] == 'all':
DIRS += [
'client',
]
if CONFIG['MOZ_DEVTOOLS'] in ('all', 'server'):
DIRS += [
'server',
'shared',
]
DIRS += [
'server',
'shared',
]
# /browser uses DIST_SUBDIR. We opt-in to this treatment when building
# DevTools for the browser to keep the root omni.ja slim for use by external XUL
# apps. Mulet also uses this since it includes /browser.
if CONFIG['MOZ_BUILD_APP'] in ('browser', 'b2g/dev'):
DIST_SUBDIR = 'browser'
export('DIST_SUBDIR')

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

@ -1989,7 +1989,7 @@ ConsoleReflowListener.prototype =
{
let frame = components.stack.caller.caller;
let filename = frame.filename;
let filename = frame ? frame.filename : null;
if (filename) {
// Because filename could be of the form "xxx.js -> xxx.js -> xxx.js",
@ -2002,8 +2002,8 @@ ConsoleReflowListener.prototype =
start: aStart,
end: aEnd,
sourceURL: filename,
sourceLine: frame.lineNumber,
functionName: frame.name
sourceLine: frame ? frame.lineNumber : null,
functionName: frame ? frame.name : null
});
},

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

@ -29,7 +29,7 @@
}
function finish() {
for each (let eventType in LISTEN_EVENTS) {
for (let eventType of LISTEN_EVENTS) {
gBrowser.removeEventListener(eventType, eventListener, true);
}
@ -43,7 +43,7 @@
function onLoad() {
gBrowser = document.getElementById("content");
for each (let eventType in LISTEN_EVENTS) {
for (let eventType of LISTEN_EVENTS) {
gBrowser.addEventListener(eventType, eventListener, true);
}

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

@ -15,7 +15,7 @@
<script type="application/javascript"><![CDATA[
var imports = [ "SimpleTest", "is", "isnot", "ok", "snapshotWindow",
"compareSnapshots", "onerror" ];
for each (var name in imports) {
for (var name of imports) {
window[name] = window.opener.wrappedJSObject[name];
}

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

@ -15,7 +15,7 @@
<script type="application/javascript"><![CDATA[
var imports = [ "SimpleTest", "is", "isnot", "ok"];
for each (var name in imports) {
for (var name of imports) {
window[name] = window.opener.wrappedJSObject[name];
}

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

@ -28,7 +28,7 @@
window.opener.wrappedJSObject.SimpleTest.is(a, b, message);
}
function finish() {
for each (let eventType in LISTEN_EVENTS) {
for (let eventType of LISTEN_EVENTS) {
gBrowser.removeEventListener(eventType, eventListener, true);
}
@ -39,7 +39,7 @@
function onLoad() {
gBrowser = document.getElementById("content");
for each (let eventType in LISTEN_EVENTS) {
for (let eventType of LISTEN_EVENTS) {
gBrowser.addEventListener(eventType, eventListener, true);
}

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

@ -32,7 +32,7 @@
window.opener.wrappedJSObject.SimpleTest.is(a, b, message);
}
function finish() {
for each (let eventType in LISTEN_EVENTS) {
for (let eventType of LISTEN_EVENTS) {
gBrowser.removeEventListener(eventType, eventListener, true);
}
@ -43,7 +43,7 @@
function onLoad() {
gBrowser = document.getElementById("content");
for each (let eventType in LISTEN_EVENTS) {
for (let eventType of LISTEN_EVENTS) {
gBrowser.addEventListener(eventType, eventListener, true);
}

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

@ -9,7 +9,7 @@
<!-- test code goes here -->
<script type="application/javascript"><![CDATA[
var imports = [ "SimpleTest", "is", "isnot", "ok", "onerror" ];
for each (var name in imports) {
for (var name of imports) {
window[name] = window.opener.wrappedJSObject[name];
}

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

@ -9,7 +9,7 @@
<!-- test code goes here -->
<script type="application/javascript"><![CDATA[
var imports = [ "SimpleTest", "is", "isnot", "ok", "onerror" ];
for each (var name in imports) {
for (var name of imports) {
window[name] = window.opener.wrappedJSObject[name];
}

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

@ -29,7 +29,7 @@
}
function finish() {
for each (let eventType in LISTEN_EVENTS) {
for (let eventType of LISTEN_EVENTS) {
gBrowser.removeEventListener(eventType, eventListener, true);
}
@ -43,7 +43,7 @@
function onLoad() {
gBrowser = document.getElementById("content");
for each (let eventType in LISTEN_EVENTS) {
for (let eventType of LISTEN_EVENTS) {
gBrowser.addEventListener(eventType, eventListener, true);
}

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

@ -3,7 +3,7 @@
*/
var imports = [ "SimpleTest", "is", "isnot", "ok", "onerror", "todo",
"todo_is", "todo_isnot" ];
for each (var name in imports) {
for (var name of imports) {
window[name] = window.opener.wrappedJSObject[name];
}
@ -125,17 +125,21 @@ function doPageNavigation(params) {
throw "Must specify onNavComplete when specifying waitForEventsOnly";
if (waitOnly && (back || forward || reload || uri))
throw "Can't specify a navigation type when using waitForEventsOnly";
for each (let anEventType in eventsToListenFor) {
for (let anEventType of eventsToListenFor) {
let eventFound = false;
if ( (anEventType == "pageshow") && (!gExpectedEvents) )
eventFound = true;
for each (let anExpectedEvent in gExpectedEvents) {
if (anExpectedEvent.type == anEventType)
eventFound = true;
if (gExpectedEvents) {
for (let anExpectedEvent of gExpectedEvents) {
if (anExpectedEvent.type == anEventType)
eventFound = true;
}
}
for each (let anExpectedEventType in gUnexpectedEvents) {
if (anExpectedEventType == anEventType)
eventFound = true;
if (gUnexpectedEvents) {
for (let anExpectedEventType of gUnexpectedEvents) {
if (anExpectedEventType == anEventType)
eventFound = true;
}
}
if (!eventFound)
throw "Event type " + anEventType + " is specified in " +
@ -148,7 +152,7 @@ function doPageNavigation(params) {
// Add an event listener for each type of event in the .eventsToListenFor
// property of the input parameters.
for each (let eventType in eventsToListenFor) {
for (let eventType of eventsToListenFor) {
dump("TEST: registering a listener for " + eventType + " events\n");
TestWindow.getBrowser().addEventListener(eventType, pageEventListener,
true);
@ -201,7 +205,7 @@ function doPageNavigation_complete(eventsToListenFor, onNavComplete,
preventBFCache) {
// Unregister our event listeners.
dump("TEST: removing event listeners\n");
for each (let eventType in eventsToListenFor) {
for (let eventType of eventsToListenFor) {
TestWindow.getBrowser().removeEventListener(eventType, pageEventListener,
true);
}

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

@ -935,6 +935,13 @@ StackFrameToStackEntry(nsIStackFrame* aStackFrame,
rv = aStackFrame->GetName(aStackEntry.mFunctionName);
NS_ENSURE_SUCCESS(rv, rv);
nsString cause;
rv = aStackFrame->GetAsyncCause(cause);
NS_ENSURE_SUCCESS(rv, rv);
if (!cause.IsEmpty()) {
aStackEntry.mAsyncCause.Construct(cause);
}
aStackEntry.mLanguage = aLanguage;
return NS_OK;
}
@ -960,6 +967,10 @@ ReifyStack(nsIStackFrame* aStack, nsTArray<ConsoleStackEntry>& aRefiedStack)
rv = stack->GetCaller(getter_AddRefs(caller));
NS_ENSURE_SUCCESS(rv, rv);
if (!caller) {
rv = stack->GetAsyncCaller(getter_AddRefs(caller));
NS_ENSURE_SUCCESS(rv, rv);
}
stack.swap(caller);
}

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

@ -97,6 +97,8 @@
#include "mozilla/dom/ipc/StructuredCloneData.h"
#include "mozilla/WebBrowserPersistLocalDocument.h"
#include "nsPrincipal.h"
#ifdef MOZ_XUL
#include "nsXULPopupManager.h"
#endif
@ -278,13 +280,20 @@ nsFrameLoader::LoadURI(nsIURI* aURI)
}
NS_IMETHODIMP
nsFrameLoader::SwitchProcessAndLoadURI(nsIURI* aURI)
nsFrameLoader::SwitchProcessAndLoadURI(nsIURI* aURI, const nsACString& aPackageId)
{
nsCOMPtr<nsIURI> URIToLoad = aURI;
RefPtr<TabParent> tp = nullptr;
nsCString signedPkgOrigin;
if (!aPackageId.IsEmpty()) {
// Only when aPackageId is not empty would signed package origin
// be meaningful.
nsPrincipal::GetOriginForURI(aURI, signedPkgOrigin);
}
MutableTabContext context;
nsresult rv = GetNewTabContext(&context);
nsresult rv = GetNewTabContext(&context, signedPkgOrigin, aPackageId);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<Element> ownerElement = mOwnerContent;
@ -3031,7 +3040,9 @@ nsFrameLoader::MaybeUpdatePrimaryTabParent(TabParentChange aChange)
}
nsresult
nsFrameLoader::GetNewTabContext(MutableTabContext* aTabContext)
nsFrameLoader::GetNewTabContext(MutableTabContext* aTabContext,
const nsACString& aSignedPkgOriginNoSuffix,
const nsACString& aPackageId)
{
nsCOMPtr<mozIApplication> ownApp = GetOwnApp();
nsCOMPtr<mozIApplication> containingApp = GetContainingApp();
@ -3051,7 +3062,11 @@ nsFrameLoader::GetNewTabContext(MutableTabContext* aTabContext)
}
attrs.mAppId = appId;
bool tabContextUpdated = aTabContext->SetTabContext(ownApp, containingApp, attrs);
// Populate packageId to signedPkg.
attrs.mSignedPkg = NS_ConvertUTF8toUTF16(aPackageId);
bool tabContextUpdated = aTabContext->SetTabContext(ownApp, containingApp,
attrs, aSignedPkgOriginNoSuffix);
NS_ENSURE_STATE(tabContextUpdated);
return NS_OK;

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

@ -318,7 +318,9 @@ private:
void InitializeBrowserAPI();
nsresult GetNewTabContext(mozilla::dom::MutableTabContext* aTabContext);
nsresult GetNewTabContext(mozilla::dom::MutableTabContext* aTabContext,
const nsACString& aSignedPkgNoSuffix = EmptyCString(),
const nsACString& aPackageId = EmptyCString());
enum TabParentChange {
eTabParentRemoved,

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

@ -191,6 +191,7 @@
#include "mozilla/dom/VRDevice.h"
#include "nsRefreshDriver.h"
#include "Layers.h"
#include "mozilla/AddonPathService.h"
#include "mozilla/BasePrincipal.h"

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

@ -16,7 +16,7 @@ interface nsIDOMElement;
interface nsITabParent;
interface nsILoadContext;
[scriptable, builtinclass, uuid(c6e00815-b7a1-4544-b309-a85b86cb1747)]
[scriptable, builtinclass, uuid(1645af04-1bc7-4363-8f2c-eb9679220ab1)]
interface nsIFrameLoader : nsISupports
{
/**
@ -52,10 +52,11 @@ interface nsIFrameLoader : nsISupports
/**
* Loads the specified URI in this frame but using a different process.
* Behaves identically to loadURI, except that this method only works
* with remote frame.
* with remote frame. For a signed package, we need to specifiy the
* package identifier.
* Throws an exception with non-remote frames.
*/
void switchProcessAndLoadURI(in nsIURI aURI);
void switchProcessAndLoadURI(in nsIURI aURI, in ACString aPackageId);
/**
* Puts the frameloader in prerendering mode.

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

@ -30,7 +30,7 @@
.QueryInterface(Ci.nsIFrameLoaderOwner)
.frameLoader;
var uri = SpecialPowers.Services.io.newURI(url, null, null);
fl.switchProcessAndLoadURI(uri);
fl.switchProcessAndLoadURI(uri, "");
}
function runTest() {

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

@ -677,15 +677,8 @@ NS_IMETHODIMP JSStackFrame::GetCaller(nsIStackFrame** aCaller)
return StackFrame::GetCaller(aCaller);
}
nsCOMPtr<nsIStackFrame> caller;
if (callerObj) {
caller = new JSStackFrame(callerObj);
} else {
// Do we really need this dummy frame? If so, we should document why... I
// guess for symmetry with the "nothing on the stack" case, which returns
// a single dummy frame?
caller = new StackFrame();
}
nsCOMPtr<nsIStackFrame> caller =
callerObj ? new JSStackFrame(callerObj) : nullptr;
caller.forget(aCaller);
if (canCache) {

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

@ -37,6 +37,7 @@
#include "mozilla/dom/CameraFacesDetectedEventBinding.h"
#include "mozilla/dom/CameraStateChangeEvent.h"
#include "mozilla/dom/CameraClosedEvent.h"
#include "mozilla/dom/VideoStreamTrack.h"
#include "mozilla/dom/BlobEvent.h"
#include "DOMCameraDetectedFace.h"
#include "mozilla/dom/BindingUtils.h"
@ -46,6 +47,45 @@ using namespace mozilla;
using namespace mozilla::dom;
using namespace mozilla::ipc;
class mozilla::TrackCreatedListener : public MediaStreamListener
{
public:
explicit TrackCreatedListener(nsDOMCameraControl* aCameraControl)
: mCameraControl(aCameraControl) {}
void Forget() { mCameraControl = nullptr; }
void DoNotifyTrackCreated(TrackID aTrackID)
{
MOZ_ASSERT(NS_IsMainThread());
if (!mCameraControl) {
return;
}
mCameraControl->TrackCreated(aTrackID);
}
void NotifyQueuedTrackChanges(MediaStreamGraph* aGraph, TrackID aID,
StreamTime aTrackOffset, uint32_t aTrackEvents,
const MediaSegment& aQueuedMedia,
MediaStream* aInputStream,
TrackID aInputTrackID) override
{
if (aTrackEvents & TRACK_EVENT_CREATED) {
nsCOMPtr<nsIRunnable> runnable =
NS_NewRunnableMethodWithArgs<TrackID>(
this, &TrackCreatedListener::DoNotifyTrackCreated, aID);
aGraph->DispatchToMainThreadAfterStreamStateUpdate(runnable.forget());
}
}
protected:
~TrackCreatedListener() {}
nsDOMCameraControl* mCameraControl;
};
#ifdef MOZ_WIDGET_GONK
StaticRefPtr<ICameraControl> nsDOMCameraControl::sCachedCameraControl;
/* static */ nsresult nsDOMCameraControl::sCachedCameraControlStartResult = NS_OK;
@ -279,6 +319,11 @@ nsDOMCameraControl::nsDOMCameraControl(uint32_t aCameraId,
#endif
mCurrentConfiguration = initialConfig.forget();
// Register a TrackCreatedListener directly on CameraPreviewMediaStream
// so we can know the TrackID of the video track.
mTrackCreatedListener = new TrackCreatedListener(this);
mInput->AddListener(mTrackCreatedListener);
// Register the playback listener directly on the camera input stream.
// We want as low latency as possible for the camera, thus avoiding
// MediaStreamGraph altogether. Don't do the regular InitStreamCommon()
@ -334,6 +379,10 @@ nsDOMCameraControl::~nsDOMCameraControl()
mInput->Destroy();
mInput = nullptr;
}
if (mTrackCreatedListener) {
mTrackCreatedListener->Forget();
mTrackCreatedListener = nullptr;
}
}
JSObject*
@ -475,6 +524,19 @@ nsDOMCameraControl::GetCameraStream() const
return mInput;
}
void
nsDOMCameraControl::TrackCreated(TrackID aTrackID) {
// This track is not connected through a port.
MediaInputPort* inputPort = nullptr;
dom::VideoStreamTrack* track =
new dom::VideoStreamTrack(this, aTrackID);
RefPtr<TrackPort> port =
new TrackPort(inputPort, track,
TrackPort::InputPortOwnership::OWNED);
mTracks.AppendElement(port.forget());
NotifyTrackAdded(track);
}
#define THROW_IF_NO_CAMERACONTROL(...) \
do { \
if (!mCameraControl) { \

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

@ -40,6 +40,7 @@ namespace dom {
class ErrorResult;
class StartRecordingHelper;
class RecorderPosterHelper;
class TrackCreatedListener;
#define NS_DOM_CAMERA_CONTROL_CID \
{ 0x3700c096, 0xf920, 0x438d, \
@ -73,6 +74,10 @@ public:
MediaStream* GetCameraStream() const override;
// Called by TrackCreatedListener when the underlying track has been created.
// XXX Bug 1124630. This can be removed with CameraPreviewMediaStream.
void TrackCreated(TrackID aTrackID);
// Attributes.
void GetEffect(nsString& aEffect, ErrorResult& aRv);
void SetEffect(const nsAString& aEffect, ErrorResult& aRv);
@ -226,6 +231,9 @@ protected:
// our viewfinder stream
RefPtr<CameraPreviewMediaStream> mInput;
// A listener on mInput for adding tracks to the DOM side.
RefPtr<TrackCreatedListener> mTrackCreatedListener;
// set once when this object is created
nsCOMPtr<nsPIDOMWindow> mWindow;

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

@ -60,6 +60,7 @@
#include "nsBidi.h"
#include "nsBidiPresUtils.h"
#include "Layers.h"
#include "LayerUserData.h"
#include "CanvasUtils.h"
#include "nsIMemoryReporter.h"
#include "nsStyleUtil.h"

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

@ -73,6 +73,7 @@ WebGL2Context::ClearBufferfv_base(GLenum buffer, GLint drawbuffer, const GLfloat
void
WebGL2Context::ClearBufferiv(GLenum buffer, GLint drawbuffer, const dom::Int32Array& value)
{
value.ComputeLengthAndData();
if (!ValidateClearBuffer("clearBufferiv", buffer, drawbuffer, value.Length())) {
return;
}
@ -93,6 +94,7 @@ WebGL2Context::ClearBufferiv(GLenum buffer, GLint drawbuffer, const dom::Sequenc
void
WebGL2Context::ClearBufferuiv(GLenum buffer, GLint drawbuffer, const dom::Uint32Array& value)
{
value.ComputeLengthAndData();
if (!ValidateClearBuffer("clearBufferuiv", buffer, drawbuffer, value.Length())) {
return;
}
@ -113,6 +115,7 @@ WebGL2Context::ClearBufferuiv(GLenum buffer, GLint drawbuffer, const dom::Sequen
void
WebGL2Context::ClearBufferfv(GLenum buffer, GLint drawbuffer, const dom::Float32Array& value)
{
value.ComputeLengthAndData();
if (!ValidateClearBuffer("clearBufferfv", buffer, drawbuffer, value.Length())) {
return;
}

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

@ -21,6 +21,7 @@
#include "ImageContainer.h"
#include "ImageEncoder.h"
#include "Layers.h"
#include "LayerUserData.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/Event.h"
#include "mozilla/dom/HTMLVideoElement.h"

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

@ -2113,7 +2113,8 @@ HTMLMediaElement::HTMLMediaElement(already_AddRefed<mozilla::dom::NodeInfo>& aNo
mPlayBlockedBecauseHidden(false),
mMediaStreamTrackListener(nullptr),
mElementInTreeState(ELEMENT_NOT_INTREE),
mHasUserInteraction(false)
mHasUserInteraction(false),
mFirstFrameLoaded(false)
{
if (!gMediaElementLog) {
gMediaElementLog = PR_NewLogModule("nsMediaElement");
@ -3445,6 +3446,11 @@ void HTMLMediaElement::FirstFrameLoaded()
{
NS_ASSERTION(!mSuspendedAfterFirstFrame, "Should not have already suspended");
if (!mFirstFrameLoaded) {
mFirstFrameLoaded = true;
UpdateReadyStateInternal();
}
ChangeDelayLoadStatus(false);
if (mDecoder && mAllowSuspendAfterFirstFrame && mPaused &&
@ -3781,7 +3787,8 @@ HTMLMediaElement::UpdateReadyStateInternal()
return;
}
if (mDownloadSuspendedByCache && mDecoder && !mDecoder->IsEndedOrShutdown()) {
if (mDownloadSuspendedByCache && mDecoder && !mDecoder->IsEndedOrShutdown() &&
mFirstFrameLoaded) {
// The decoder has signaled that the download has been suspended by the
// media cache. So move readyState into HAVE_ENOUGH_DATA, in case there's
// script waiting for a "canplaythrough" event; without this forced
@ -3800,7 +3807,9 @@ HTMLMediaElement::UpdateReadyStateInternal()
if (NextFrameStatus() != MediaDecoderOwner::NEXT_FRAME_AVAILABLE) {
LOG(LogLevel::Debug, ("MediaElement %p UpdateReadyStateInternal() "
"Next frame not available", this));
ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_CURRENT_DATA);
if (mFirstFrameLoaded) {
ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_CURRENT_DATA);
}
if (!mWaitingFired && NextFrameStatus() == MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE_BUFFERING) {
FireTimeUpdate(false);
DispatchAsyncEvent(NS_LITERAL_STRING("waiting"));
@ -3809,6 +3818,12 @@ HTMLMediaElement::UpdateReadyStateInternal()
return;
}
if (!mFirstFrameLoaded) {
// We haven't yet loaded the first frame, making us unable to determine
// if we have enough valid data at the present stage.
return;
}
if (mSrcStream) {
LOG(LogLevel::Debug, ("MediaElement %p UpdateReadyStateInternal() "
"Stream HAVE_ENOUGH_DATA", this));
@ -3824,8 +3839,7 @@ HTMLMediaElement::UpdateReadyStateInternal()
// autoplay elements for live streams will never play. Otherwise we
// move to HAVE_ENOUGH_DATA if we can play through the entire media
// without stopping to buffer.
if (mDecoder->CanPlayThrough())
{
if (mDecoder->CanPlayThrough()) {
LOG(LogLevel::Debug, ("MediaElement %p UpdateReadyStateInternal() "
"Decoder can play through", this));
ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_ENOUGH_DATA);

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

@ -1513,6 +1513,9 @@ private:
// Indicates if user has interacted with the element.
// Used to block autoplay when disabled.
bool mHasUserInteraction;
// True if the first frame has been successfully loaded.
bool mFirstFrameLoaded;
};
} // namespace dom

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

@ -35,6 +35,12 @@ class nsIPrincipal;
namespace mozilla {
#if DEUBG
#define LOG(args...) printf_stderr(args)
#else
#define LOG(...)
#endif
#ifdef MOZ_CHILD_PERMISSIONS
static bool
@ -118,11 +124,52 @@ AssertAppStatus(PBrowserParent* aActor,
return CheckAppStatusHelper(app, aStatus);
}
// A general purpose helper function to check permission against the origin
// rather than mozIApplication.
static bool
CheckOriginPermission(const nsACString& aOrigin, const char* aPermission)
{
LOG("CheckOriginPermission: %s, %s\n", nsCString(aOrigin).get(), aPermission);
nsIScriptSecurityManager *securityManager =
nsContentUtils::GetSecurityManager();
nsCOMPtr<nsIPrincipal> principal;
securityManager->CreateCodebasePrincipalFromOrigin(aOrigin,
getter_AddRefs(principal));
nsCOMPtr<nsIPermissionManager> permMgr = services::GetPermissionManager();
NS_ENSURE_TRUE(permMgr, false);
uint32_t perm;
nsresult rv = permMgr->TestExactPermissionFromPrincipal(principal, aPermission, &perm);
NS_ENSURE_SUCCESS(rv, false);
LOG("Permission %s for %s: %d\n", aPermission, nsCString(aOrigin).get(), perm);
return nsIPermissionManager::ALLOW_ACTION == perm;
}
bool
AssertAppProcess(TabContext& aContext,
AssertAppProcessType aType,
const char* aCapability)
{
const mozilla::OriginAttributes& attr = aContext.OriginAttributesRef();
nsCString suffix;
attr.CreateSuffix(suffix);
if (!aContext.SignedPkgOriginNoSuffix().IsEmpty()) {
LOG("TabContext owning signed package origin: %s, originAttr; %s\n",
nsCString(aContext.SignedPkgOriginNoSuffix()).get(),
suffix.get());
}
// Do a origin-based permission check if the TabContext owns a signed package.
if (!aContext.SignedPkgOriginNoSuffix().IsEmpty() &&
(ASSERT_APP_HAS_PERMISSION == aType || ASSERT_APP_PROCESS_PERMISSION == aType)) {
nsCString origin = aContext.SignedPkgOriginNoSuffix() + suffix;
return CheckOriginPermission(origin, aCapability);
}
nsCOMPtr<mozIApplication> app = aContext.GetOwnOrContainingApp();
return CheckAppTypeHelper(app, aType, aCapability, aContext.IsBrowserElement());

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

@ -37,6 +37,11 @@ struct FrameIPCTabContext
// The ID of the app containing this app/browser frame, if applicable.
uint32_t frameOwnerAppId;
// The origin without originAttribute suffix for a signed package.
// This value would be empty if the TabContext doesn't own a signed
// package.
nsCString signedPkgOriginNoSuffix;
};
// IPCTabContext is an analog to mozilla::dom::TabContext. Both specify an

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

@ -158,11 +158,17 @@ TabContext::OriginAttributesRef() const
return mOriginAttributes;
}
const nsACString&
TabContext::SignedPkgOriginNoSuffix() const
{
return mSignedPkgOriginNoSuffix;
}
bool
TabContext::SetTabContext(mozIApplication* aOwnApp,
mozIApplication* aAppFrameOwnerApp,
const OriginAttributes& aOriginAttributes)
const OriginAttributes& aOriginAttributes,
const nsACString& aSignedPkgOriginNoSuffix)
{
NS_ENSURE_FALSE(mInitialized, false);
@ -192,6 +198,7 @@ TabContext::SetTabContext(mozIApplication* aOwnApp,
mContainingAppId = containingAppId;
mOwnApp = aOwnApp;
mContainingApp = aAppFrameOwnerApp;
mSignedPkgOriginNoSuffix = aSignedPkgOriginNoSuffix;
return true;
}
@ -200,7 +207,9 @@ TabContext::AsIPCTabContext() const
{
nsAutoCString originSuffix;
mOriginAttributes.CreateSuffix(originSuffix);
return IPCTabContext(FrameIPCTabContext(originSuffix, mContainingAppId));
return IPCTabContext(FrameIPCTabContext(originSuffix,
mContainingAppId,
mSignedPkgOriginNoSuffix));
}
static already_AddRefed<mozIApplication>
@ -221,6 +230,7 @@ MaybeInvalidTabContext::MaybeInvalidTabContext(const IPCTabContext& aParams)
uint32_t containingAppId = NO_APP_ID;
OriginAttributes originAttributes = OriginAttributes();
nsAutoCString originSuffix;
nsAutoCString signedPkgOriginNoSuffix;
const IPCTabContextUnion& contextUnion = aParams.contextUnion();
switch(contextUnion.type()) {
@ -276,6 +286,7 @@ MaybeInvalidTabContext::MaybeInvalidTabContext(const IPCTabContext& aParams)
contextUnion.get_FrameIPCTabContext();
containingAppId = ipcContext.frameOwnerAppId();
signedPkgOriginNoSuffix = ipcContext.signedPkgOriginNoSuffix();
originSuffix = ipcContext.originSuffix();
originAttributes.PopulateFromSuffix(originSuffix);
break;
@ -305,7 +316,8 @@ MaybeInvalidTabContext::MaybeInvalidTabContext(const IPCTabContext& aParams)
bool rv;
rv = mTabContext.SetTabContext(ownApp,
containingApp,
originAttributes);
originAttributes,
signedPkgOriginNoSuffix);
if (!rv) {
mInvalidReason = "Couldn't initialize TabContext.";
}

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

@ -110,6 +110,12 @@ public:
*/
const OriginAttributes& OriginAttributesRef() const;
/**
* Returns the origin associated with the tab (w/o suffix) if this tab owns
* a signed packaged content.
*/
const nsACString& SignedPkgOriginNoSuffix() const;
protected:
friend class MaybeInvalidTabContext;
@ -136,7 +142,8 @@ protected:
*/
bool SetTabContext(mozIApplication* aOwnApp,
mozIApplication* aAppFrameOwnerApp,
const OriginAttributes& aOriginAttributes);
const OriginAttributes& aOriginAttributes,
const nsACString& aSignedPkgOriginNoSuffix);
private:
/**
@ -167,6 +174,13 @@ private:
*/
OriginAttributes mOriginAttributes;
/**
* The signed package origin without suffix. Since the signed packaged
* web content is always loaded in a separate process, it makes sense
* that we store this immutable value in TabContext. If the TabContext
* doesn't own a signed package, this value would be empty.
*/
nsCString mSignedPkgOriginNoSuffix;
};
/**
@ -184,11 +198,13 @@ public:
bool SetTabContext(mozIApplication* aOwnApp,
mozIApplication* aAppFrameOwnerApp,
const OriginAttributes& aOriginAttributes)
const OriginAttributes& aOriginAttributes,
const nsACString& aSignedPkgOriginNoSuffix = EmptyCString())
{
return TabContext::SetTabContext(aOwnApp,
aAppFrameOwnerApp,
aOriginAttributes);
aOriginAttributes,
aSignedPkgOriginNoSuffix);
}
};

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

@ -518,7 +518,8 @@ TabParent::ShouldSwitchProcess(nsIChannel* aChannel)
}
void
TabParent::OnStartSignedPackageRequest(nsIChannel* aChannel)
TabParent::OnStartSignedPackageRequest(nsIChannel* aChannel,
const nsACString& aPackageId)
{
if (!ShouldSwitchProcess(aChannel)) {
return;
@ -537,7 +538,7 @@ TabParent::OnStartSignedPackageRequest(nsIChannel* aChannel)
RefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
NS_ENSURE_TRUE_VOID(frameLoader);
nsresult rv = frameLoader->SwitchProcessAndLoadURI(uri);
nsresult rv = frameLoader->SwitchProcessAndLoadURI(uri, aPackageId);
if (NS_FAILED(rv)) {
NS_WARNING("Failed to switch process.");
}

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

@ -456,7 +456,8 @@ public:
// Called by HttpChannelParent. The function may use a new process to
// reload the URI associated with the given channel.
void OnStartSignedPackageRequest(nsIChannel* aChannel);
void OnStartSignedPackageRequest(nsIChannel* aChannel,
const nsACString& aPackageId);
protected:
bool ReceiveMessage(const nsString& aMessage,

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

@ -36,108 +36,66 @@ using namespace mozilla::layers;
const TrackID TRACK_VIDEO_PRIMARY = 1;
/**
* TrackPort is a representation of a MediaStreamTrack-MediaInputPort pair
* that make up a link between the Owned stream and the Playback stream.
*
* Semantically, the track is the identifier/key and the port the value of this
* connection.
*
* The input port can be shared between several TrackPorts. This is the case
* for DOMMediaStream's mPlaybackPort which forwards all tracks in its
* mOwnedStream automatically.
*
* If the MediaStreamTrack is owned by another DOMMediaStream (called A) than
* the one owning the TrackPort (called B), the input port (locked to the
* MediaStreamTrack's TrackID) connects A's mOwnedStream to B's mPlaybackStream.
*
* A TrackPort may never leave the DOMMediaStream it was created in. Internal
* use only.
*/
class DOMMediaStream::TrackPort
DOMMediaStream::TrackPort::TrackPort(MediaInputPort* aInputPort,
MediaStreamTrack* aTrack,
const InputPortOwnership aOwnership)
: mInputPort(aInputPort)
, mTrack(aTrack)
, mOwnership(aOwnership)
{
public:
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(TrackPort)
NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(TrackPort)
// XXX Bug 1124630. nsDOMCameraControl requires adding a track without and
// input port.
// MOZ_ASSERT(mInputPort);
MOZ_ASSERT(mTrack);
enum class InputPortOwnership {
OWNED = 1,
EXTERNAL
};
MOZ_COUNT_CTOR(TrackPort);
}
TrackPort(MediaInputPort* aInputPort,
MediaStreamTrack* aTrack,
const InputPortOwnership aOwnership)
: mInputPort(aInputPort)
, mTrack(aTrack)
, mOwnership(aOwnership)
{
MOZ_ASSERT(mInputPort);
MOZ_ASSERT(mTrack);
DOMMediaStream::TrackPort::~TrackPort()
{
MOZ_COUNT_DTOR(TrackPort);
MOZ_COUNT_CTOR(TrackPort);
if (mOwnership == InputPortOwnership::OWNED && mInputPort) {
mInputPort->Destroy();
mInputPort = nullptr;
}
}
protected:
virtual ~TrackPort()
{
MOZ_COUNT_DTOR(TrackPort);
if (mOwnership == InputPortOwnership::OWNED && mInputPort) {
mInputPort->Destroy();
mInputPort = nullptr;
}
void
DOMMediaStream::TrackPort::DestroyInputPort()
{
if (mInputPort) {
mInputPort->Destroy();
mInputPort = nullptr;
}
}
public:
void DestroyInputPort()
{
if (mInputPort) {
mInputPort->Destroy();
mInputPort = nullptr;
}
MediaStream*
DOMMediaStream::TrackPort::GetSource() const
{
return mInputPort ? mInputPort->GetSource() : nullptr;
}
TrackID
DOMMediaStream::TrackPort::GetSourceTrackId() const
{
return mInputPort ? mInputPort->GetSourceTrackId() : TRACK_INVALID;
}
void
DOMMediaStream::TrackPort::BlockTrackId(TrackID aTrackId)
{
if (mInputPort) {
mInputPort->BlockTrackId(aTrackId);
}
/**
* Returns the source stream of the input port.
*/
MediaStream* GetSource() const { return mInputPort ? mInputPort->GetSource()
: nullptr; }
/**
* Returns the track ID this track is locked to in the source stream of the
* input port.
*/
TrackID GetSourceTrackId() const { return mInputPort ? mInputPort->GetSourceTrackId()
: TRACK_INVALID; }
MediaInputPort* GetInputPort() const { return mInputPort; }
MediaStreamTrack* GetTrack() const { return mTrack; }
/**
* Blocks aTrackId from going into mInputPort unless the port has been
* destroyed.
*/
void BlockTrackId(TrackID aTrackId)
{
if (mInputPort) {
mInputPort->BlockTrackId(aTrackId);
}
}
private:
RefPtr<MediaInputPort> mInputPort;
RefPtr<MediaStreamTrack> mTrack;
// Defines if we've been given ownership of the input port or if it's owned
// externally. The owner is responsible for destroying the port.
const InputPortOwnership mOwnership;
};
}
NS_IMPL_CYCLE_COLLECTION(DOMMediaStream::TrackPort, mTrack)
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(DOMMediaStream::TrackPort, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(DOMMediaStream::TrackPort, Release)
/**
* Listener registered on the Owned stream to detect added and ended owned
* tracks for keeping the list of MediaStreamTracks in sync with the tracks

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

@ -173,7 +173,6 @@ class MediaStreamDirectListener;
*/
class DOMMediaStream : public DOMEventTargetHelper
{
class TrackPort;
friend class DOMLocalMediaStream;
typedef dom::MediaStreamTrack MediaStreamTrack;
typedef dom::AudioStreamTrack AudioStreamTrack;
@ -208,7 +207,83 @@ public:
virtual ~TrackListener() {}
};
DOMMediaStream();
/**
* TrackPort is a representation of a MediaStreamTrack-MediaInputPort pair
* that make up a link between the Owned stream and the Playback stream.
*
* Semantically, the track is the identifier/key and the port the value of this
* connection.
*
* The input port can be shared between several TrackPorts. This is the case
* for DOMMediaStream's mPlaybackPort which forwards all tracks in its
* mOwnedStream automatically.
*
* If the MediaStreamTrack is owned by another DOMMediaStream (called A) than
* the one owning the TrackPort (called B), the input port (locked to the
* MediaStreamTrack's TrackID) connects A's mOwnedStream to B's mPlaybackStream.
*
* A TrackPort may never leave the DOMMediaStream it was created in. Internal
* use only.
*/
class TrackPort
{
public:
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(TrackPort)
NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(TrackPort)
/**
* Indicates MediaInputPort ownership to the TrackPort.
*
* OWNED - Owned by the TrackPort itself. TrackPort must destroy the
* input port when it's destructed.
* EXTERNAL - Owned by another entity. It's the caller's responsibility to
* ensure the the MediaInputPort outlives the TrackPort.
*/
enum class InputPortOwnership {
OWNED = 1,
EXTERNAL
};
TrackPort(MediaInputPort* aInputPort,
MediaStreamTrack* aTrack,
const InputPortOwnership aOwnership);
protected:
virtual ~TrackPort();
public:
void DestroyInputPort();
/**
* Returns the source stream of the input port.
*/
MediaStream* GetSource() const;
/**
* Returns the track ID this track is locked to in the source stream of the
* input port.
*/
TrackID GetSourceTrackId() const;
MediaInputPort* GetInputPort() const { return mInputPort; }
MediaStreamTrack* GetTrack() const { return mTrack; }
/**
* Blocks aTrackId from going into mInputPort unless the port has been
* destroyed.
*/
void BlockTrackId(TrackID aTrackId);
private:
RefPtr<MediaInputPort> mInputPort;
RefPtr<MediaStreamTrack> mTrack;
// Defines if we've been given ownership of the input port or if it's owned
// externally. The owner is responsible for destroying the port.
const InputPortOwnership mOwnership;
};
DOMMediaStream();
NS_DECL_ISUPPORTS_INHERITED
NS_REALLY_FORWARD_NSIDOMEVENTTARGET(DOMEventTargetHelper)

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

@ -1246,6 +1246,18 @@ MediaDecoderStateMachine::SetDormant(bool aDormant)
return;
}
if (mMetadataRequest.Exists()) {
if (mPendingDormant && mPendingDormant.ref() != aDormant && !aDormant) {
// We already have a dormant request pending; the new request would have
// resumed from dormant, we can just cancel any pending dormant requests.
mPendingDormant.reset();
} else {
mPendingDormant = Some(aDormant);
}
return;
}
mPendingDormant.reset();
DECODER_LOG("SetDormant=%d", aDormant);
if (aDormant) {
@ -1906,6 +1918,11 @@ MediaDecoderStateMachine::OnMetadataRead(MetadataHolder* aMetadata)
MOZ_ASSERT(mState == DECODER_STATE_DECODING_METADATA);
mMetadataRequest.Complete();
if (mPendingDormant) {
SetDormant(mPendingDormant.ref());
return;
}
// Set mode to PLAYBACK after reading metadata.
mResource->SetReadMode(MediaCacheStream::MODE_PLAYBACK);
mDecoder->DispatchSetMediaSeekable(mReader->IsMediaSeekable());

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

@ -1086,6 +1086,9 @@ private:
// been written to the MediaStream.
Watchable<bool> mAudioCompleted;
// Set if MDSM receives dormant request during reading metadata.
Maybe<bool> mPendingDormant;
// Flag whether we notify metadata before decoding the first frame or after.
//
// Note that the odd semantics here are designed to replicate the current

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

@ -92,7 +92,6 @@ MediaFormatReader::Shutdown()
MOZ_ASSERT(OnTaskQueue());
mDemuxerInitRequest.DisconnectIfExists();
mDecodersInitRequest.DisconnectIfExists();
mMetadataPromise.RejectIfExists(ReadMetadataFailureReason::METADATA_ERROR, __func__);
mSeekPromise.RejectIfExists(NS_ERROR_FAILURE, __func__);
mSkipRequest.DisconnectIfExists();
@ -102,6 +101,7 @@ MediaFormatReader::Shutdown()
if (mAudio.HasPromise()) {
mAudio.RejectPromise(CANCELED, __func__);
}
mAudio.mInitPromise.DisconnectIfExists();
mAudio.mDecoder->Shutdown();
mAudio.mDecoder = nullptr;
}
@ -122,6 +122,7 @@ MediaFormatReader::Shutdown()
if (mVideo.HasPromise()) {
mVideo.RejectPromise(CANCELED, __func__);
}
mVideo.mInitPromise.DisconnectIfExists();
mVideo.mDecoder->Shutdown();
mVideo.mDecoder = nullptr;
}
@ -248,24 +249,18 @@ MediaFormatReader::AsyncReadMetadata()
{
MOZ_ASSERT(OnTaskQueue());
RefPtr<MetadataPromise> p = mMetadataPromise.Ensure(__func__);
MOZ_DIAGNOSTIC_ASSERT(mMetadataPromise.IsEmpty());
if (mInitDone) {
// We are returning from dormant.
if (!EnsureDecodersCreated()) {
mMetadataPromise.Reject(ReadMetadataFailureReason::METADATA_ERROR, __func__);
return p;
}
MOZ_ASSERT(!mDecodersInitRequest.Exists());
if (EnsureDecodersInitialized()) {
RefPtr<MetadataHolder> metadata = new MetadataHolder();
metadata->mInfo = mInfo;
metadata->mTags = nullptr;
mMetadataPromise.Resolve(metadata, __func__);
}
return p;
RefPtr<MetadataHolder> metadata = new MetadataHolder();
metadata->mInfo = mInfo;
metadata->mTags = nullptr;
return MetadataPromise::CreateAndResolve(metadata, __func__);
}
RefPtr<MetadataPromise> p = mMetadataPromise.Ensure(__func__);
mDemuxerInitRequest.Begin(mDemuxer->Init()
->Then(OwnerThread(), __func__, this,
&MediaFormatReader::OnDemuxerInitDone,
@ -341,24 +336,11 @@ MediaFormatReader::OnDemuxerInitDone(nsresult)
return;
}
if (IsWaitingOnCDMResource()) {
// Decoder can't be allocated before CDM resource is ready, so resolving the
// mMetadataPromise here to wait for CDM on MDSM.
mInitDone = true;
RefPtr<MetadataHolder> metadata = new MetadataHolder();
metadata->mInfo = mInfo;
metadata->mTags = nullptr;
mMetadataPromise.Resolve(metadata, __func__);
return;
}
if (!EnsureDecodersCreated()) {
mMetadataPromise.Reject(ReadMetadataFailureReason::METADATA_ERROR, __func__);
return;
}
MOZ_ASSERT(!mDecodersInitRequest.Exists());
EnsureDecodersInitialized();
mInitDone = true;
RefPtr<MetadataHolder> metadata = new MetadataHolder();
metadata->mInfo = mInfo;
metadata->mTags = nullptr;
mMetadataPromise.Resolve(metadata, __func__);
}
void
@ -447,81 +429,6 @@ MediaFormatReader::EnsureDecoderInitialized(TrackType aTrack)
return false;
}
bool
MediaFormatReader::EnsureDecodersInitialized()
{
MOZ_ASSERT(OnTaskQueue());
MOZ_ASSERT(mVideo.mDecoder || mAudio.mDecoder);
// DecodeDemuxedSample() could call this function before mDecodersInitRequest
// is completed. And it is ok to return false here because DecodeDemuxedSample
// will call ScheduleUpdate() again.
// It also avoids calling decoder->Init() multiple times.
if (mDecodersInitRequest.Exists()) {
MOZ_ASSERT(false);
return false;
}
nsTArray<RefPtr<MediaDataDecoder::InitPromise>> promises;
if (mVideo.mDecoder && !mVideo.mDecoderInitialized) {
MOZ_ASSERT(!mVideo.mInitPromise.Exists());
promises.AppendElement(mVideo.mDecoder->Init());
}
if (mAudio.mDecoder && !mAudio.mDecoderInitialized) {
MOZ_ASSERT(!mAudio.mInitPromise.Exists());
promises.AppendElement(mAudio.mDecoder->Init());
}
if (promises.Length()) {
mDecodersInitRequest.Begin(MediaDataDecoder::InitPromise::All(OwnerThread(), promises)
->Then(OwnerThread(), __func__, this,
&MediaFormatReader::OnDecoderInitDone,
&MediaFormatReader::OnDecoderInitFailed));
}
LOG("Init decoders: audio: %p, audio init: %d, video: %p, video init: %d",
mAudio.mDecoder.get(), mAudio.mDecoderInitialized,
mVideo.mDecoder.get(), mVideo.mDecoderInitialized);
// Return false if any decoder is under initialization.
return !promises.Length();
}
void
MediaFormatReader::OnDecoderInitDone(const nsTArray<TrackType>& aTrackTypes)
{
MOZ_ASSERT(OnTaskQueue());
mDecodersInitRequest.Complete();
for (const auto& track : aTrackTypes) {
auto& decoder = GetDecoderData(track);
decoder.mDecoderInitialized = true;
}
MOZ_ASSERT(!mMetadataPromise.IsEmpty());
mInitDone = true;
RefPtr<MetadataHolder> metadata = new MetadataHolder();
metadata->mInfo = mInfo;
metadata->mTags = nullptr;
mMetadataPromise.Resolve(metadata, __func__);
}
void
MediaFormatReader::OnDecoderInitFailed(MediaDataDecoder::DecoderFailureReason aReason)
{
MOZ_ASSERT(OnTaskQueue());
mDecodersInitRequest.Complete();
NS_WARNING("Failed to init decoder");
mMetadataPromise.RejectIfExists(ReadMetadataFailureReason::METADATA_ERROR, __func__);
NotifyError(TrackType::kAudioTrack);
NotifyError(TrackType::kVideoTrack);
}
void
MediaFormatReader::ReadUpdatedMetadata(MediaInfo* aInfo)
{
@ -1614,6 +1521,7 @@ void MediaFormatReader::ReleaseMediaResources()
mVideoFrameContainer->ClearCurrentFrame();
}
if (mVideo.mDecoder) {
mVideo.mInitPromise.DisconnectIfExists();
mVideo.mDecoder->Shutdown();
mVideo.mDecoder = nullptr;
}

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

@ -123,9 +123,6 @@ private:
void ReturnOutput(MediaData* aData, TrackType aTrack);
bool EnsureDecodersCreated();
// It returns true when all decoders are initialized. False when there is pending
// initialization.
bool EnsureDecodersInitialized();
bool EnsureDecoderInitialized(TrackType aTrack);
// Enqueues a task to call Update(aTrack) on the decoder task queue.
@ -368,9 +365,6 @@ private:
DecoderData& GetDecoderData(TrackType aTrack);
void OnDecoderInitDone(const nsTArray<TrackType>& aTrackTypes);
void OnDecoderInitFailed(MediaDataDecoder::DecoderFailureReason aReason);
// Demuxer objects.
RefPtr<MediaDataDemuxer> mDemuxer;
bool mDemuxerInitDone;
@ -449,9 +443,6 @@ private:
Maybe<media::TimeUnit> mPendingSeekTime;
MozPromiseHolder<SeekPromise> mSeekPromise;
// Pending decoders initialization.
MozPromiseRequestHolder<MediaDataDecoder::InitPromise::AllPromiseType> mDecodersInitRequest;
RefPtr<VideoFrameContainer> mVideoFrameContainer;
layers::ImageContainer* GetImageContainer();

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

@ -22,7 +22,7 @@ function startTest(test, token) {
ok(false, test.name + " should not fire '" + type + "' event");
}};
var events = [
'loadedmetadata', 'load',
'loadeddata', 'load',
'canplay', 'canplaythrough',
'playing'
];

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

@ -81,6 +81,7 @@ dictionary ConsoleStackEntry {
unsigned long columnNumber = 0;
DOMString functionName = "";
unsigned long language = 0;
DOMString? asyncCause;
};
dictionary ConsoleTimerStart {

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

@ -1,6 +1,6 @@
load 351236-1.html
load 407062-1.html
load 419563-1.xhtml
skip-if(winWidget) load 428844-1.html # bug 471185
load 428844-1.html
load 461049-1.html
asserts(0-1) asserts-if(winWidget||Android,0-2) load removing-editable-xslt.html # bug 500847

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

@ -8,7 +8,3 @@ include('/toolkit/toolkit.mozbuild')
if CONFIG['MOZ_EXTENSIONS']:
DIRS += ['/extensions']
DIRS += [
'/devtools',
]

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

@ -1100,7 +1100,7 @@ DrawTargetCairo::ClearRect(const Rect& aRect)
if (!mContext || aRect.Width() <= 0 || aRect.Height() <= 0 ||
!IsFinite(aRect.X()) || !IsFinite(aRect.Width()) ||
!IsFinite(aRect.Y()) || !IsFinite(aRect.Height())) {
gfxCriticalError(CriticalLog::DefaultOptions(false)) << "ClearRect with invalid argument " << gfx::hexa(mContext) << " with " << aRect.Width() << "x" << aRect.Height() << " [" << aRect.X() << ", " << aRect.Y() << "]";
gfxCriticalNote << "ClearRect with invalid argument " << gfx::hexa(mContext) << " with " << aRect.Width() << "x" << aRect.Height() << " [" << aRect.X() << ", " << aRect.Y() << "]";
}
cairo_set_antialias(mContext, CAIRO_ANTIALIAS_NONE);

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

@ -140,7 +140,7 @@ public:
RefPtr<ID2D1BitmapBrush> brush;
HRESULT hr = rt->CreateBitmapBrush(mOldSurfBitmap, D2D1::BitmapBrushProperties(), D2D1::BrushProperties(), getter_AddRefs(brush));
if (FAILED(hr)) {
gfxCriticalError(CriticalLog::DefaultOptions(false)) << "[D2D] CreateBitmapBrush failure " << hexa(hr);
gfxCriticalNote << "[D2D] CreateBitmapBrush failure " << hexa(hr);
return;
}

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

@ -905,7 +905,7 @@ DrawTargetD2D1::Init(const IntSize &aSize, SurfaceFormat aFormat)
if (mDC->GetMaximumBitmapSize() < UINT32(aSize.width) ||
mDC->GetMaximumBitmapSize() < UINT32(aSize.height)) {
// This is 'ok', so don't assert
gfxCriticalError(CriticalLog::DefaultOptions(false)) << "[D2D1.1] Attempt to use unsupported surface size " << aSize;
gfxCriticalNote << "[D2D1.1] Attempt to use unsupported surface size " << aSize;
return false;
}

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

@ -0,0 +1,28 @@
/* -*- 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 GFX_LAYERUSERDATA_H
#define GFX_LAYERUSERDATA_H
namespace mozilla {
namespace layers {
/**
* Base class for userdata objects attached to layers and layer managers.
*
* We define it here in a separate header so clients only need to include
* this header for their class definitions, rather than pulling in Layers.h.
* Everything else in Layers.h should be forward-declarable.
*/
class LayerUserData {
public:
virtual ~LayerUserData() {}
};
} // namespace layers
} // namespace mozilla
#endif /* GFX_LAYERUSERDATA_H */

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

@ -205,6 +205,19 @@ LayerManager::AreComponentAlphaLayersEnabled()
return gfxPrefs::ComponentAlphaEnabled();
}
/*static*/ void
LayerManager::LayerUserDataDestroy(void* data)
{
delete static_cast<LayerUserData*>(data);
}
nsAutoPtr<LayerUserData>
LayerManager::RemoveUserData(void* aKey)
{
nsAutoPtr<LayerUserData> d(static_cast<LayerUserData*>(mUserData.Remove(static_cast<gfx::UserDataKey*>(aKey))));
return d;
}
//--------------------------------------------------
// Layer
@ -2058,6 +2071,13 @@ Layer::IsBackfaceHidden()
return false;
}
nsAutoPtr<LayerUserData>
Layer::RemoveUserData(void* aKey)
{
nsAutoPtr<LayerUserData> d(static_cast<LayerUserData*>(mUserData.Remove(static_cast<gfx::UserDataKey*>(aKey))));
return d;
}
void
PaintedLayer::PrintInfo(std::stringstream& aStream, const char* aPrefix)
{

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

@ -103,13 +103,8 @@ class LayersPacket;
virtual const char* Name() const override { return n; } \
virtual LayerType GetType() const override { return e; }
/**
* Base class for userdata objects attached to layers and layer managers.
*/
class LayerUserData {
public:
virtual ~LayerUserData() {}
};
// Defined in LayerUserData.h; please include that file instead.
class LayerUserData;
/*
* Motivation: For truly smooth animation and video playback, we need to
@ -137,11 +132,6 @@ public:
* BasicLayerManager for such an implementation.
*/
static void LayerManagerUserDataDestroy(void *data)
{
delete static_cast<LayerUserData*>(data);
}
/**
* A LayerManager controls a tree of layers. All layers in the tree
* must use the same LayerManager.
@ -509,16 +499,13 @@ public:
*/
void SetUserData(void* aKey, LayerUserData* aData)
{
mUserData.Add(static_cast<gfx::UserDataKey*>(aKey), aData, LayerManagerUserDataDestroy);
mUserData.Add(static_cast<gfx::UserDataKey*>(aKey), aData, LayerUserDataDestroy);
}
/**
* This can be used anytime. Ownership passes to the caller!
*/
nsAutoPtr<LayerUserData> RemoveUserData(void* aKey)
{
nsAutoPtr<LayerUserData> d(static_cast<LayerUserData*>(mUserData.Remove(static_cast<gfx::UserDataKey*>(aKey))));
return d;
}
nsAutoPtr<LayerUserData> RemoveUserData(void* aKey);
/**
* This getter can be used anytime.
*/
@ -676,6 +663,8 @@ public:
return false;
}
static void LayerUserDataDestroy(void* data);
protected:
RefPtr<Layer> mRoot;
gfx::UserData mUserData;
@ -1389,16 +1378,12 @@ public:
*/
void SetUserData(void* aKey, LayerUserData* aData)
{
mUserData.Add(static_cast<gfx::UserDataKey*>(aKey), aData, LayerManagerUserDataDestroy);
mUserData.Add(static_cast<gfx::UserDataKey*>(aKey), aData, LayerManager::LayerUserDataDestroy);
}
/**
* This can be used anytime. Ownership passes to the caller!
*/
nsAutoPtr<LayerUserData> RemoveUserData(void* aKey)
{
nsAutoPtr<LayerUserData> d(static_cast<LayerUserData*>(mUserData.Remove(static_cast<gfx::UserDataKey*>(aKey))));
return d;
}
nsAutoPtr<LayerUserData> RemoveUserData(void* aKey);
/**
* This getter can be used anytime.
*/
@ -1472,10 +1457,13 @@ public:
bool Extend3DContext() {
return GetContentFlags() & CONTENT_EXTEND_3D_CONTEXT;
}
bool Is3DContextLeaf() {
return !Extend3DContext() && GetParent() &&
bool Combines3DTransformWithAncestors() {
return GetParent() &&
reinterpret_cast<Layer*>(GetParent())->Extend3DContext();
}
bool Is3DContextLeaf() {
return !Extend3DContext() && Combines3DTransformWithAncestors();
}
/**
* It is true if the user can see the back of the layer and the
* backface is hidden. The compositor should skip the layer if the

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

@ -864,6 +864,10 @@ InstallLayerClipPreserves3D(gfxContext* aTarget, Layer* aLayer)
if (!clipRect) {
return;
}
MOZ_ASSERT(!aLayer->Extend3DContext() ||
!aLayer->Combines3DTransformWithAncestors(),
"Layers in a preserve 3D context have no clip"
" except leaves and the estabisher!");
Layer* parent = aLayer->GetParent();
Matrix4x4 transform3d =

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

@ -135,8 +135,7 @@ private:
if (SUCCEEDED(hr))
return false;
gfxCriticalError(CriticalLog::DefaultOptions(false))
<< "[D3D11] " << aContext << " failed: " << hexa(hr);
gfxCriticalNote << "[D3D11] " << aContext << " failed: " << hexa(hr);
return true;
}
@ -198,8 +197,7 @@ CompositorD3D11::Initialize()
mDevice->GetImmediateContext(getter_AddRefs(mContext));
if (!mContext) {
gfxCriticalError(CriticalLog::DefaultOptions(false))
<< "[D3D11] failed to get immediate context";
gfxCriticalNote << "[D3D11] failed to get immediate context";
return false;
}
@ -485,7 +483,7 @@ CompositorD3D11::CreateRenderTarget(const gfx::IntRect& aRect,
RefPtr<ID3D11Texture2D> texture;
HRESULT hr = mDevice->CreateTexture2D(&desc, nullptr, getter_AddRefs(texture));
if (Failed(hr) || !texture) {
gfxCriticalError(gfxCriticalError::DefaultOptions(false)) << "Failed in CreateRenderTarget";
gfxCriticalNote << "Failed in CreateRenderTarget " << hexa(hr);
return nullptr;
}
@ -519,7 +517,7 @@ CompositorD3D11::CreateRenderTargetFromSource(const gfx::IntRect &aRect,
HRESULT hr = mDevice->CreateTexture2D(&desc, nullptr, getter_AddRefs(texture));
NS_ASSERTION(texture, "Could not create texture");
if (Failed(hr) || !texture) {
gfxCriticalError(gfxCriticalError::DefaultOptions(false)) << "Failed in CreateRenderTargetFromSource";
gfxCriticalNote << "Failed in CreateRenderTargetFromSource " << hexa(hr);
return nullptr;
}
@ -1235,7 +1233,7 @@ CompositorD3D11::UpdateRenderTarget()
{
EnsureSize();
if (!VerifyBufferSize()) {
gfxCriticalError(gfxCriticalError::DefaultOptions(false)) << "Failed VerifyBufferSize in UpdateRenderTarget " << mSize;
gfxCriticalNote << "Failed VerifyBufferSize in UpdateRenderTarget " << mSize;
return;
}
@ -1244,7 +1242,7 @@ CompositorD3D11::UpdateRenderTarget()
}
if (mSize.width <= 0 || mSize.height <= 0) {
gfxCriticalError(gfxCriticalError::DefaultOptions(false)) << "Invalid size in UpdateRenderTarget " << mSize;
gfxCriticalNote << "Invalid size in UpdateRenderTarget " << mSize;
return;
}
@ -1261,7 +1259,7 @@ CompositorD3D11::UpdateRenderTarget()
}
}
if (Failed(hr)) {
gfxCriticalError(gfxCriticalError::DefaultOptions(false)) << "Failed in UpdateRenderTarget";
gfxCriticalNote << "Failed in UpdateRenderTarget " << hexa(hr);
return;
}
@ -1444,8 +1442,7 @@ CompositorD3D11::Failed(HRESULT hr, const char* aContext)
if (SUCCEEDED(hr))
return false;
gfxCriticalError(CriticalLog::DefaultOptions(false))
<< "[D3D11] " << aContext << " failed: " << hexa(hr);
gfxCriticalNote << "[D3D11] " << aContext << " failed: " << hexa(hr);
return true;
}

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

@ -75,7 +75,7 @@ TextureSourceD3D11::GetShaderResourceView()
mTexture->GetDevice(getter_AddRefs(device));
HRESULT hr = device->CreateShaderResourceView(mTexture, nullptr, getter_AddRefs(mSRV));
if (FAILED(hr)) {
gfxCriticalError(CriticalLog::DefaultOptions(false)) << "[D3D11] TextureSourceD3D11:GetShaderResourceView CreateSRV failure " << gfx::hexa(hr);
gfxCriticalNote << "[D3D11] TextureSourceD3D11:GetShaderResourceView CreateSRV failure " << gfx::hexa(hr);
return nullptr;
}
}
@ -1129,7 +1129,7 @@ DataTextureSourceD3D11::GetShaderResourceView()
mTileTextures[mCurrentTile]->GetDevice(getter_AddRefs(device));
HRESULT hr = device->CreateShaderResourceView(mTileTextures[mCurrentTile], nullptr, getter_AddRefs(mTileSRVs[mCurrentTile]));
if (FAILED(hr)) {
gfxCriticalError(CriticalLog::DefaultOptions(false)) << "[D3D11] DataTextureSourceD3D11:GetShaderResourceView CreateSRV failure " << gfx::hexa(hr);
gfxCriticalNote << "[D3D11] DataTextureSourceD3D11:GetShaderResourceView CreateSRV failure " << gfx::hexa(hr);
return nullptr;
}
}

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

@ -37,6 +37,7 @@ EXPORTS += [
'LayerSorter.h',
'LayersTypes.h',
'LayerTreeInvalidation.h',
'LayerUserData.h',
'opengl/Composer2D.h',
'opengl/OGLShaderProgram.h',
'opengl/TexturePoolOGL.h',

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

@ -424,14 +424,14 @@ void
D3D11LayersCrashGuard::LogCrashRecovery()
{
RecordTelemetry(TelemetryState::RecoveredFromCrash);
gfxCriticalError(CriticalLog::DefaultOptions(false)) << "D3D11 layers just crashed; D3D11 will be disabled.";
gfxCriticalNote << "D3D11 layers just crashed; D3D11 will be disabled.";
}
void
D3D11LayersCrashGuard::LogFeatureDisabled()
{
RecordTelemetry(TelemetryState::FeatureDisabled);
gfxCriticalError(CriticalLog::DefaultOptions(false)) << "D3D11 layers disabled due to a prior crash.";
gfxCriticalNote << "D3D11 layers disabled due to a prior crash.";
}
void
@ -468,13 +468,13 @@ D3D9VideoCrashGuard::UpdateEnvironment()
void
D3D9VideoCrashGuard::LogCrashRecovery()
{
gfxCriticalError(CriticalLog::DefaultOptions(false)) << "DXVA2D3D9 just crashed; hardware video will be disabled.";
gfxCriticalNote << "DXVA2D3D9 just crashed; hardware video will be disabled.";
}
void
D3D9VideoCrashGuard::LogFeatureDisabled()
{
gfxCriticalError(CriticalLog::DefaultOptions(false)) << "DXVA2D3D9 video decoding is disabled due to a previous crash.";
gfxCriticalNote << "DXVA2D3D9 video decoding is disabled due to a previous crash.";
}
GLContextCrashGuard::GLContextCrashGuard(dom::ContentParent* aContentParent)
@ -525,13 +525,13 @@ GLContextCrashGuard::UpdateEnvironment()
void
GLContextCrashGuard::LogCrashRecovery()
{
gfxCriticalError(CriticalLog::DefaultOptions(false)) << "GLContext just crashed and is now disabled.";
gfxCriticalNote << "GLContext just crashed and is now disabled.";
}
void
GLContextCrashGuard::LogFeatureDisabled()
{
gfxCriticalError(CriticalLog::DefaultOptions(false)) << "GLContext is disabled due to a previous crash.";
gfxCriticalNote << "GLContext is disabled due to a previous crash.";
}
} // namespace gfx

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

@ -255,8 +255,7 @@
#define NS_THEME_WIN_MEDIA_TOOLBOX 222
#define NS_THEME_WIN_BROWSER_TAB_BAR_TOOLBOX 223
// Unified toolbar and titlebar elements on the Mac
#define NS_THEME_MOZ_MAC_UNIFIED_TOOLBAR 224
// Titlebar elements on the Mac
#define NS_THEME_MOZ_MAC_FULLSCREEN_BUTTON 226
// Mac help button

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

@ -6,6 +6,7 @@
#include "TestLayers.h"
#include "gtest/gtest.h"
#include "gmock/gmock.h"
#include "LayerUserData.h"
#include "mozilla/layers/LayerMetricsWrapper.h"
#include "mozilla/layers/CompositorParent.h"

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

@ -1912,7 +1912,7 @@ bool DoesD3D11TextureSharingWorkInternal(ID3D11Device *device, DXGI_FORMAT forma
// This if(FAILED()) is the one that actually fails on systems affected by bug 1083071.
if (FAILED(device->CreateShaderResourceView(sharedTexture, NULL, getter_AddRefs(sharedView)))) {
gfxCriticalError(CriticalLog::DefaultOptions(false)) << "CreateShaderResourceView failed for format" << format;
gfxCriticalNote << "CreateShaderResourceView failed for format" << format;
return false;
}

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

@ -31,7 +31,7 @@ gfxWindowsSurface::gfxWindowsSurface(HDC dc, uint32_t flags) :
Init(cairo_win32_printing_surface_create(mDC));
mForPrinting = true;
if (!mSurfaceValid) {
gfxCriticalError(gfxCriticalError::DefaultOptions(false)) << "Invalid printing surface";
gfxCriticalNote << "Invalid printing surface";
}
} else
#endif

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

@ -27,7 +27,12 @@ class AsyncNotifyRunnable;
class AsyncNotifyCurrentStateRunnable;
class Image;
// Image progress bitflags.
/**
* Image progress bitflags.
*
* See CheckProgressConsistency() for the invariants we enforce about the
* ordering dependencies betweeen these flags.
*/
enum {
FLAG_SIZE_AVAILABLE = 1u << 0, // STATUS_SIZE_AVAILABLE
FLAG_DECODE_COMPLETE = 1u << 1, // STATUS_DECODE_COMPLETE

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

@ -1225,9 +1225,7 @@ VectorImage::OnSVGDocumentError()
if (mProgressTracker) {
// Notify observers about the error and unblock page load.
Progress progress = FLAG_DECODE_COMPLETE |
FLAG_ONLOAD_UNBLOCKED |
FLAG_HAS_ERROR;
Progress progress = FLAG_ONLOAD_UNBLOCKED | FLAG_HAS_ERROR;
// Merge in any saved progress from OnImageDataComplete.
if (mLoadProgress) {

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

@ -76,7 +76,7 @@ bool TestManyChildAllocsChild::RecvGo()
fail("can't send Hello()");
}
size_t len = ManagedPTestManyChildAllocsSubChild().Length();
size_t len = ManagedPTestManyChildAllocsSubChild().Count();
if (NALLOCS != len)
fail("expected %lu kids, got %lu", NALLOCS, len);

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

@ -1,6 +1,7 @@
#include "TestMultiMgrs.h"
#include "IPDLUnitTests.h" // fail etc.
#include "mozilla/ipc/ProtocolUtils.h"
namespace mozilla {
namespace _ipdltest {
@ -70,17 +71,17 @@ TestMultiMgrsRightChild::RecvPTestMultiMgrsBottomConstructor(
bool
TestMultiMgrsChild::RecvCheck()
{
if (1 != ManagedPTestMultiMgrsLeftChild().Length())
if (1 != ManagedPTestMultiMgrsLeftChild().Count())
fail("where's leftie?");
if (1 != ManagedPTestMultiMgrsRightChild().Length())
if (1 != ManagedPTestMultiMgrsRightChild().Count())
fail("where's rightie?");
TestMultiMgrsLeftChild* leftie =
static_cast<TestMultiMgrsLeftChild*>(
ManagedPTestMultiMgrsLeftChild()[0]);
LoneManagedOrNull(ManagedPTestMultiMgrsLeftChild()));
TestMultiMgrsRightChild* rightie =
static_cast<TestMultiMgrsRightChild*>(
ManagedPTestMultiMgrsRightChild()[0]);
LoneManagedOrNull(ManagedPTestMultiMgrsRightChild()));
if (!leftie->HasChild(mBottomL))
fail("leftie didn't have a child it was supposed to!");

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

@ -230,7 +230,7 @@ ValidateArrayView(JSContext* cx, AsmJSModule::Global& global, HandleValue global
bool tac = IsTypedArrayConstructor(v, global.viewType());
bool stac = IsSharedTypedArrayConstructor(v, global.viewType());
if (!((tac || stac) && stac == isShared))
if (!(tac || (stac && isShared)))
return LinkFail(cx, "bad typed array constructor");
return true;

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

@ -314,6 +314,10 @@ class AsmJSModule
MOZ_ASSERT(pod.which_ == ArrayView || pod.which_ == SharedArrayView || pod.which_ == ArrayViewCtor);
return pod.u.viewType_;
}
void makeViewShared() {
MOZ_ASSERT(pod.which_ == ArrayView);
pod.which_ = SharedArrayView;
}
PropertyName* mathName() const {
MOZ_ASSERT(pod.which_ == MathBuiltinFunction);
return name_;
@ -1106,6 +1110,15 @@ class AsmJSModule
return pod.isSharedView_ == shared;
return !pod.isSharedView_ || shared;
}
void setViewsAreShared() {
if (pod.hasArrayView_)
pod.isSharedView_ = true;
for (size_t i=0 ; i < globals_.length() ; i++) {
Global& g = globals_[i];
if (g.which() == Global::ArrayView)
g.makeViewShared();
}
}
/*************************************************************************/

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

@ -773,6 +773,10 @@ class MOZ_STACK_CLASS ModuleValidator
MOZ_ASSERT(isAnyArrayView());
return u.viewInfo.isSharedView_;
}
void setViewIsSharedView() {
MOZ_ASSERT(isAnyArrayView());
u.viewInfo.isSharedView_ = true;
}
bool isMathFunction() const {
return which_ == MathBuiltinFunction;
}
@ -918,6 +922,7 @@ class MOZ_STACK_CLASS ModuleValidator
bool canValidateChangeHeap_;
bool hasChangeHeap_;
bool supportsSimd_;
bool atomicsPresent_;
ScopedJSDeletePtr<ModuleCompileResults> compileResults_;
DebugOnly<bool> finishedFunctionBodies_;
@ -943,6 +948,7 @@ class MOZ_STACK_CLASS ModuleValidator
canValidateChangeHeap_(false),
hasChangeHeap_(false),
supportsSimd_(cx->jitSupportsSimd()),
atomicsPresent_(false),
compileResults_(nullptr),
finishedFunctionBodies_(false)
{
@ -1155,6 +1161,7 @@ class MOZ_STACK_CLASS ModuleValidator
Global* global = moduleLifo_.new_<Global>(Global::AtomicsBuiltinFunction);
if (!global)
return false;
atomicsPresent_ = true;
global->u.atomicsBuiltinFunc_ = func;
return globals_.putNew(varName, global);
}
@ -1509,6 +1516,14 @@ class MOZ_STACK_CLASS ModuleValidator
}
void startFunctionBodies() {
if (atomicsPresent_) {
for (GlobalMap::Range r = globals_.all() ; !r.empty() ; r.popFront()) {
Global* g = r.front().value();
if (g->isAnyArrayView())
g->setViewIsSharedView();
}
module_->setViewsAreShared();
}
module_->startFunctionBodies();
}
bool finishFunctionBodies(ScopedJSDeletePtr<ModuleCompileResults>* compileResults) {

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

@ -0,0 +1,119 @@
// Transitional test cases, useful while Odin accepts both
// "Int32Array" and "SharedInt32Array" to construct a view onto shared
// memory but the former only when an atomic operation is referenced,
// as per spec. Eventually it will stop accepting "SharedInt32Array",
// because that name is going away.
//
// These should not run with --no-asmjs.
if (!isAsmJSCompilationAvailable())
quit(0);
//////////////////////////////////////////////////////////////////////
//
// Int8Array can be used on SharedArrayBuffer, if atomics are present
function m1(stdlib, ffi, heap) {
"use asm";
var i8 = new stdlib.Int8Array(heap);
var add = stdlib.Atomics.add;
function f() {
add(i8, 0, 1);
return 37;
}
return { f:f }
}
assertEq(isAsmJSModule(m1), true);
var { f } = m1(this, {}, new SharedArrayBuffer(65536));
assertEq(f(), 37);
//////////////////////////////////////////////////////////////////////
//
// SharedInt8Array can still be used on SharedArrayBuffer.
// (SharedInt8Array will eventually disappear, and this
// test case with it.)
function m2(stdlib, ffi, heap) {
"use asm";
var i8 = new stdlib.SharedInt8Array(heap);
var add = stdlib.Atomics.add;
function g() {
add(i8, 0, 1);
return 42;
}
return { g:g }
}
assertEq(isAsmJSModule(m2), true);
var { g } = m2(this, {}, new SharedArrayBuffer(65536));
assertEq(g(), 42);
//////////////////////////////////////////////////////////////////////
//
// SharedInt8Array still cannot be used on ArrayBuffer, even without
// atomics present.
// (SharedInt8Array will eventually disappear, and this
// test case with it.)
function m3(stdlib, ffi, heap) {
"use asm";
var i8 = new stdlib.SharedInt8Array(heap);
function h() {
return i8[0]|0;
}
return { h:h }
}
// Running the shell with -w you should see an error here.
assertEq(isAsmJSModule(m3), true);
try {
var wasThrown = false;
m3(this, {}, new ArrayBuffer(65536));
}
catch (e) {
wasThrown = true;
}
assertEq(wasThrown, true);
//////////////////////////////////////////////////////////////////////
//
// Int8Array cannot be used on SharedArrayBuffer if atomics are not imported.
// One argument for the restriction is that there are some optimizations
// that are legal if the memory is known not to be shared that are illegal
// when it is shared.
function m4(stdlib, ffi, heap) {
"use asm";
var i8 = new stdlib.Int8Array(heap);
function i() {
return i8[0]|0;
}
return { i:i }
}
assertEq(isAsmJSModule(m4), true);
// An error is not actually thrown because the link failure drops us
// back to JS execution and then the Int8Array constructor will copy data
// from the SharedArrayBuffer.
//
// Running the shell with -w you should see an error here.
var { i } = m4(this, {}, new SharedArrayBuffer(65536));
assertEq(isAsmJSFunction(i), false);

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

@ -1,5 +1,5 @@
// |jit-test| test-also-noasmjs
if (!this.SharedArrayBuffer || !this.SharedInt32Array || !this.Atomics)
if (!this.SharedArrayBuffer || !this.Atomics)
quit();
// The code duplication below is very far from elegant but provides
@ -8,6 +8,27 @@ if (!this.SharedArrayBuffer || !this.SharedInt32Array || !this.Atomics)
load(libdir + "asm.js");
load(libdir + "asserts.js");
// This hack allows the test cases to run with --no-asmjs: the field values
// are basically ignored in asm.js mode, and the correct (Firefox-specific)
// field values are used in non-asm.js mode. If run in a non-Firefox
// browser that does not have the parallel type hierarchy this should also
// work.
//
// This hack will be removed when the parallel type hierarchy is removed
// from Firefox, bug 1176214.
const atomicStdlib = {
Atomics: Atomics,
Int8Array: this.SharedInt8Array ? SharedInt8Array : Int8Array,
Uint8Array: this.SharedUint8Array ? SharedUint8Array : Uint8Array,
Int16Array: this.SharedInt16Array ? SharedInt16Array : Int16Array,
Uint16Array: this.SharedUint16Array ? SharedUint16Array : Uint16Array,
Int32Array: this.SharedInt32Array ? SharedInt32Array : Int32Array,
Uint32Array: this.SharedUint32Array ? SharedUint32Array : Uint32Array,
Float32Array: this.SharedFloat32Array ? SharedFloat32Array : Float32Array,
Float64Array: this.SharedFloat64Array ? SharedFloat64Array : Float64Array
};
var loadModule_int32_code =
USE_ASM + `
var atomic_fence = stdlib.Atomics.fence;
@ -21,7 +42,7 @@ var loadModule_int32_code =
var atomic_or = stdlib.Atomics.or;
var atomic_xor = stdlib.Atomics.xor;
var i32a = new stdlib.SharedInt32Array(heap);
var i32a = new stdlib.Int32Array(heap);
function do_fence() {
atomic_fence();
@ -233,7 +254,7 @@ var loadModule_int32 = asmCompile('stdlib', 'foreign', 'heap', loadModule_int32_
function test_int32(heap) {
var i32a = new SharedInt32Array(heap);
var i32m = asmLink(loadModule_int32, this, {}, heap);
var i32m = asmLink(loadModule_int32, atomicStdlib, {}, heap);
var size = SharedInt32Array.BYTES_PER_ELEMENT;
@ -338,7 +359,7 @@ var loadModule_uint32_code =
var atomic_or = stdlib.Atomics.or;
var atomic_xor = stdlib.Atomics.xor;
var i32a = new stdlib.SharedUint32Array(heap);
var i32a = new stdlib.Uint32Array(heap);
// Load element 0
function do_load() {
@ -516,7 +537,7 @@ var loadModule_uint32 = asmCompile('stdlib', 'foreign', 'heap', loadModule_uint3
function test_uint32(heap) {
var i32a = new SharedUint32Array(heap);
var i32m = loadModule_uint32(this, {}, heap);
var i32m = loadModule_uint32(atomicStdlib, {}, heap);
var size = SharedUint32Array.BYTES_PER_ELEMENT;
@ -619,7 +640,7 @@ var loadModule_int16_code =
var atomic_or = stdlib.Atomics.or;
var atomic_xor = stdlib.Atomics.xor;
var i16a = new stdlib.SharedInt16Array(heap);
var i16a = new stdlib.Int16Array(heap);
function do_fence() {
atomic_fence();
@ -802,7 +823,7 @@ var loadModule_int16 = asmCompile('stdlib', 'foreign', 'heap', loadModule_int16_
function test_int16(heap) {
var i16a = new SharedInt16Array(heap);
var i16m = loadModule_int16(this, {}, heap);
var i16m = loadModule_int16(atomicStdlib, {}, heap);
var size = SharedInt16Array.BYTES_PER_ELEMENT;
@ -914,7 +935,7 @@ var loadModule_uint16_code =
var atomic_or = stdlib.Atomics.or;
var atomic_xor = stdlib.Atomics.xor;
var i16a = new stdlib.SharedUint16Array(heap);
var i16a = new stdlib.Uint16Array(heap);
// Load element 0
function do_load() {
@ -1092,7 +1113,7 @@ var loadModule_uint16 = asmCompile('stdlib', 'foreign', 'heap', loadModule_uint1
function test_uint16(heap) {
var i16a = new SharedUint16Array(heap);
var i16m = loadModule_uint16(this, {}, heap);
var i16m = loadModule_uint16(atomicStdlib, {}, heap);
var size = SharedUint16Array.BYTES_PER_ELEMENT;
@ -1202,7 +1223,7 @@ var loadModule_int8_code =
var atomic_or = stdlib.Atomics.or;
var atomic_xor = stdlib.Atomics.xor;
var i8a = new stdlib.SharedInt8Array(heap);
var i8a = new stdlib.Int8Array(heap);
// Load element 0
function do_load() {
@ -1380,7 +1401,7 @@ var loadModule_int8 = asmCompile('stdlib', 'foreign', 'heap', loadModule_int8_co
function test_int8(heap) {
var i8a = new SharedInt8Array(heap);
var i8m = loadModule_int8(this, {}, heap);
var i8m = loadModule_int8(atomicStdlib, {}, heap);
for ( var i=0 ; i < i8a.length ; i++ )
i8a[i] = 0;
@ -1483,7 +1504,7 @@ var loadModule_uint8_code =
var atomic_or = stdlib.Atomics.or;
var atomic_xor = stdlib.Atomics.xor;
var i8a = new stdlib.SharedUint8Array(heap);
var i8a = new stdlib.Uint8Array(heap);
// Load element 0
function do_load() {
@ -1661,7 +1682,7 @@ var loadModule_uint8 = asmCompile('stdlib', 'foreign', 'heap', loadModule_uint8_
function test_uint8(heap) {
var i8a = new SharedUint8Array(heap);
var i8m = loadModule_uint8(this, {}, heap);
var i8m = loadModule_uint8(atomicStdlib, {}, heap);
for ( var i=0 ; i < i8a.length ; i++ )
i8a[i] = 0;
@ -1816,7 +1837,7 @@ var loadModule_misc_code =
var loadModule_misc = asmCompile('stdlib', 'foreign', 'heap', loadModule_misc_code);
function test_misc(heap) {
var misc = loadModule_misc(this, {}, heap);
var misc = loadModule_misc(atomicStdlib, {}, heap);
assertEq(misc.ilf1(), 1);
assertEq(misc.ilf2(), 1);
@ -1848,7 +1869,7 @@ setARMHwCapFlags('vfp');
asmCompile('stdlib', 'ffi', 'heap',
USE_ASM + `
var atomic_exchange = stdlib.Atomics.exchange;
var i8a = new stdlib.SharedInt8Array(heap);
var i8a = new stdlib.Int8Array(heap);
function do_xchg() {
var v = 0;

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