зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c to b2ginbound, a=merge
--HG-- extra : commitid : IGU3ThODOFR
This commit is contained in:
Коммит
2625db041f
|
@ -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;
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче