Merge mozilla-central to b2g-inbound

This commit is contained in:
Carsten "Tomcat" Book 2014-06-03 14:56:10 +02:00
commit 6cdcde547c
233 changed files with 4295 additions and 1107 deletions

View File

@ -976,6 +976,9 @@ pref("browser.autofocus", false);
// Enable wakelock
pref("dom.wakelock.enabled", true);
// Disable touch caret by default
pref("touchcaret.enabled", false);
// Enable sync and mozId with Firefox Accounts.
#ifdef MOZ_SERVICES_FXACCOUNTS
pref("services.sync.fxaccounts.enabled", true);

View File

@ -671,6 +671,9 @@
@BINPATH@/res/table-remove-row-active.gif
@BINPATH@/res/table-remove-row-hover.gif
@BINPATH@/res/table-remove-row.gif
@BINPATH@/res/text_selection_handle.png
@BINPATH@/res/text_selection_handle@1.5.png
@BINPATH@/res/text_selection_handle@2.png
@BINPATH@/res/grabber.gif
#ifdef XP_MACOSX
@BINPATH@/res/cursors/*

View File

@ -1517,6 +1517,9 @@ pref("security.csp.speccompliant", true);
// Block insecure active content on https pages
pref("security.mixed_content.block_active_content", true);
// 1 = allow MITM for certificate pinning checks.
pref("security.cert_pinning.enforcement_level", 1);
// Override the Gecko-default value of false for Firefox.
pref("plain_text.wrap_long_lines", true);

View File

@ -2,10 +2,15 @@
skip-if = e10s # Bug ?????? - devtools tests disabled with e10s
subsuite = devtools
support-files =
doc_layoutview_iframe1.html
doc_layoutview_iframe2.html
head.js
[browser_layoutview.js]
[browser_layoutview_rotate-labels-on-sides.js]
[browser_layoutview_update-after-navigation.js]
[browser_layoutview_update-after-reload.js]
[browser_layoutview_update-in-iframes.js]
[browser_editablemodel.js]
[browser_editablemodel_allproperties.js]
[browser_editablemodel_border.js]

View File

@ -0,0 +1,99 @@
/* 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";
// Test that the layout-view continues to work after a page navigation and that
// it also works after going back
let test = asyncTest(function*() {
yield addTab(TEST_URL_ROOT + "doc_layoutview_iframe1.html");
let {toolbox, inspector, view} = yield openLayoutView();
yield runTests(inspector, view);
yield destroyToolbox(inspector);
});
addTest("Test that the layout-view works on the first page",
function*(inspector, view) {
info("Selecting the test node");
yield selectNode("p", inspector);
info("Checking that the layout-view shows the right value");
let paddingElt = view.doc.querySelector(".padding.top > span");
is(paddingElt.textContent, "50");
info("Listening for layout-view changes and modifying the padding");
let onUpdated = waitForUpdate(inspector);
getNode("p").style.padding = "20px";
yield onUpdated;
ok(true, "Layout-view got updated");
info("Checking that the layout-view shows the right value after update");
is(paddingElt.textContent, "20");
});
addTest("Navigate to the second page",
function*(inspector, view) {
yield navigateTo(TEST_URL_ROOT + "doc_layoutview_iframe2.html");
yield inspector.once("markuploaded");
});
addTest("Test that the layout-view works on the second page",
function*(inspector, view) {
info("Selecting the test node");
yield selectNode("p", inspector);
info("Checking that the layout-view shows the right value");
let sizeElt = view.doc.querySelector(".size > span");
is(sizeElt.textContent, "100x100");
info("Listening for layout-view changes and modifying the size");
let onUpdated = waitForUpdate(inspector);
getNode("p").style.width = "200px";
yield onUpdated;
ok(true, "Layout-view got updated");
info("Checking that the layout-view shows the right value after update");
is(sizeElt.textContent, "200x100");
});
addTest("Go back to the first page",
function*(inspector, view) {
content.history.back();
yield inspector.once("markuploaded");
});
addTest("Test that the layout-view works on the first page after going back",
function*(inspector, view) {
info("Selecting the test node");
yield selectNode("p", inspector);
info("Checking that the layout-view shows the right value, which is the" +
"modified value from step one because of the bfcache");
let paddingElt = view.doc.querySelector(".padding.top > span");
is(paddingElt.textContent, "20");
info("Listening for layout-view changes and modifying the padding");
let onUpdated = waitForUpdate(inspector);
getNode("p").style.padding = "100px";
yield onUpdated;
ok(true, "Layout-view got updated");
info("Checking that the layout-view shows the right value after update");
is(paddingElt.textContent, "100");
});
function navigateTo(url) {
info("Navigating to " + url);
let def = promise.defer();
gBrowser.selectedBrowser.addEventListener("load", function onload() {
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
info("URL " + url + " loading complete");
waitForFocus(def.resolve, content);
}, true);
content.location = url;
return def.promise;
}

View File

@ -0,0 +1,42 @@
/* 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";
// Test that the layout-view continues to work after the page is reloaded
let test = asyncTest(function*() {
yield addTab(TEST_URL_ROOT + "doc_layoutview_iframe1.html");
let {toolbox, inspector, view} = yield openLayoutView();
info("Test that the layout-view works on the first page");
yield assertLayoutView(inspector, view);
info("Reload the page");
content.location.reload();
yield inspector.once("markuploaded");
info("Test that the layout-view works on the reloaded page");
yield assertLayoutView(inspector, view);
yield destroyToolbox(inspector);
});
function* assertLayoutView(inspector, view) {
info("Selecting the test node");
yield selectNode("p", inspector);
info("Checking that the layout-view shows the right value");
let paddingElt = view.doc.querySelector(".padding.top > span");
is(paddingElt.textContent, "50");
info("Listening for layout-view changes and modifying the padding");
let onUpdated = waitForUpdate(inspector);
getNode("p").style.padding = "20px";
yield onUpdated;
ok(true, "Layout-view got updated");
info("Checking that the layout-view shows the right value after update");
is(paddingElt.textContent, "20");
}

View File

@ -0,0 +1,61 @@
/* 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";
// Test that the layout-view for elements within iframes also updates when they
// change
let test = asyncTest(function*() {
yield addTab(TEST_URL_ROOT + "doc_layoutview_iframe1.html");
let iframe2 = getNode("iframe").contentDocument.querySelector("iframe");
let {toolbox, inspector, view} = yield openLayoutView();
yield runTests(inspector, view, iframe2);
yield destroyToolbox(inspector);
});
addTest("Test that resizing an element in an iframe updates its box model",
function*(inspector, view, iframe2) {
info("Selecting the nested test node");
let node = iframe2.contentDocument.querySelector("div");
yield selectNode(node, inspector);
info("Checking that the layout-view shows the right value");
let sizeElt = view.doc.querySelector(".size > span");
is(sizeElt.textContent, "400x200");
info("Listening for layout-view changes and modifying its size");
let onUpdated = waitForUpdate(inspector);
node.style.width = "200px";
yield onUpdated;
ok(true, "Layout-view got updated");
info("Checking that the layout-view shows the right value after update");
is(sizeElt.textContent, "200x200");
});
addTest("Test reflows are still sent to the layout-view after deleting an iframe",
function*(inspector, view, iframe2) {
info("Deleting the iframe2");
iframe2.remove();
yield inspector.once("inspector-updated");
info("Selecting the test node in iframe1");
let node = getNode("iframe").contentDocument.querySelector("p");
yield selectNode(node, inspector);
info("Checking that the layout-view shows the right value");
let sizeElt = view.doc.querySelector(".size > span");
is(sizeElt.textContent, "100x100");
info("Listening for layout-view changes and modifying its size");
let onUpdated = waitForUpdate(inspector);
node.style.width = "200px";
yield onUpdated;
ok(true, "Layout-view got updated");
info("Checking that the layout-view shows the right value after update");
is(sizeElt.textContent, "200x100");
});

View File

@ -0,0 +1,3 @@
<!DOCTYPE html>
<p style="padding:50px;color:#f06;">Root page</p>
<iframe src="doc_layoutview_iframe2.html"></iframe>

View File

@ -0,0 +1,3 @@
<!DOCTYPE html>
<p style="width:100px;height:100px;background:red;">iframe 1</p>
<iframe src="data:text/html,<div style='width:400px;height:200px;background:yellow;'>iframe 2</div>"></iframe>

View File

@ -23,6 +23,7 @@ support-files = head.js
[browser_scratchpad_falsy.js]
[browser_scratchpad_edit_ui_updates.js]
[browser_scratchpad_revert_to_saved.js]
[browser_scratchpad_run_error_goto_line.js]
[browser_scratchpad_contexts.js]
[browser_scratchpad_execute_print.js]
[browser_scratchpad_files.js]
@ -34,6 +35,7 @@ support-files = head.js
[browser_scratchpad_throw_output.js]
[browser_scratchpad_pprint-02.js]
[browser_scratchpad_pprint.js]
[browser_scratchpad_pprint_error_goto_line.js]
[browser_scratchpad_restore.js]
[browser_scratchpad_tab_switch.js]
[browser_scratchpad_ui.js]

View File

@ -0,0 +1,66 @@
/* -*- Mode: js; tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2; fill-column: 80 -*- */
/* 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";
function test()
{
waitForExplicitFinish();
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
openScratchpad(runTests);
}, true);
content.location = "data:text/html;charset=utf8,test Scratchpad pretty print error goto line.";
}
function testJumpToPrettyPrintError(sp, error, remark) {
info("will test jumpToLine after prettyPrint error" + remark);
// CodeMirror lines and columns are 0-based, Scratchpad UI and error
// stack are 1-based.
is(/Invalid regexp flag \(3:10\)/.test(error), true, "prettyPrint expects error in editor text:\n" + error);
const errorLine = 3, errorColumn = 10;
const editorDoc = sp.editor.container.contentDocument;
sp.editor.jumpToLine();
const lineInput = editorDoc.querySelector("input");
const errorLocation = lineInput.value;
const [ inputLine, inputColumn ] = errorLocation.split(":");
is(inputLine, errorLine, "jumpToLine input field is set from editor selection (line)");
is(inputColumn, errorColumn, "jumpToLine input field is set from editor selection (column)");
EventUtils.synthesizeKey("VK_RETURN", { }, editorDoc.defaultView);
// CodeMirror lines and columns are 0-based, Scratchpad UI and error
// stack are 1-based.
const cursor = sp.editor.getCursor();
is(inputLine, cursor.line + 1, "jumpToLine goto error location (line)");
is(inputColumn, cursor.ch + 1, "jumpToLine goto error location (column)");
}
function runTests(sw, sp)
{
sp.setText([
"// line 1",
"// line 2",
"var re = /a bad /regexp/; // line 3 is an obvious syntax error!",
"// line 4",
"// line 5",
""
].join("\n"));
sp.prettyPrint().then(aFulfill => {
ok(false, "Expecting Invalid regexp flag (3:10)");
finish();
}, error => {
testJumpToPrettyPrintError(sp, error, " (Bug 1005471, first time)");
});
sp.prettyPrint().then(aFulfill => {
ok(false, "Expecting Invalid regexp flag (3:10)");
finish();
}, error => {
// Second time verifies bug in earlier implementation fixed.
testJumpToPrettyPrintError(sp, error, " (second time)");
finish();
});
}

View File

@ -0,0 +1,49 @@
/* -*- Mode: js; tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2; fill-column: 80 -*- */
/* 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";
function test()
{
waitForExplicitFinish();
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
openScratchpad(runTests);
}, true);
content.location = "data:text/html;charset=utf8,test Scratchpad pretty print.";
}
function runTests(sw)
{
const sp = sw.Scratchpad;
sp.setText([
"// line 1",
"// line 2",
"var re = /a bad /regexp/; // line 3 is an obvious syntax error!",
"// line 4",
"// line 5",
""
].join("\n"));
sp.run().then(() => {
// CodeMirror lines and columns are 0-based, Scratchpad UI and error
// stack are 1-based.
let errorLine = 3;
let editorDoc = sp.editor.container.contentDocument;
sp.editor.jumpToLine();
let lineInput = editorDoc.querySelector("input");
let inputLine = lineInput.value;
is(inputLine, errorLine, "jumpToLine input field is set from editor selection");
EventUtils.synthesizeKey("VK_RETURN", { }, editorDoc.defaultView);
// CodeMirror lines and columns are 0-based, Scratchpad UI and error
// stack are 1-based.
let cursor = sp.editor.getCursor();
is(cursor.line + 1, inputLine, "jumpToLine goto error location (line)");
is(cursor.ch + 1, 1, "jumpToLine goto error location (column)");
finish();
});
}

View File

@ -1,3 +1,4 @@
/* -*- Mode: js; tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2; fill-column: 80 -*- */
/* vim:set ts=2 sw=2 sts=2 et 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
@ -20,6 +21,11 @@ const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.x
// while shifting to a line which was initially out of view.
const MAX_VERTICAL_OFFSET = 3;
// Match @Scratchpad/N:LINE[:COLUMN] or (LINE[:COLUMN]) anywhere at an end of
// line in text selection.
const RE_SCRATCHPAD_ERROR = /(?:@Scratchpad\/\d+:|\()(\d+):?(\d+)?(?:\)|\n)/;
const RE_JUMP_TO_LINE = /^(\d+):?(\d+)?/;
const {Promise: promise} = Cu.import("resource://gre/modules/Promise.jsm", {});
const events = require("devtools/toolkit/event-emitter");
@ -752,7 +758,28 @@ Editor.prototype = {
div.appendChild(txt);
div.appendChild(inp);
this.openDialog(div, (line) => this.setCursor({ line: line - 1, ch: 0 }));
if (!this.hasMultipleSelections()) {
let cm = editors.get(this);
let sel = cm.getSelection();
// Scratchpad inserts and selects a comment after an error happens:
// "@Scratchpad/1:10:2". Parse this to get the line and column.
// In the string above this is line 10, column 2.
let match = sel.match(RE_SCRATCHPAD_ERROR);
if (match) {
let [ , line, column ] = match;
inp.value = column ? line + ":" + column : line;
inp.selectionStart = inp.selectionEnd = inp.value.length;
}
}
this.openDialog(div, (line) => {
// Handle LINE:COLUMN as well as LINE
let match = line.toString().match(RE_JUMP_TO_LINE);
if (match) {
let [ , line, column ] = match;
this.setCursor({line: line - 1, ch: column ? column - 1 : 0 });
}
});
},
/**

View File

@ -22,6 +22,7 @@ support-files =
[browser_editor_basic.js]
[browser_editor_cursor.js]
[browser_editor_goto_line.js]
[browser_editor_history.js]
[browser_editor_markers.js]
[browser_editor_movelines.js]

View File

@ -0,0 +1,130 @@
/* -*- Mode: js; tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2; fill-column: 80 -*- */
/* 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";
function testJumpToLine (ed, inputLine, expectCursor) {
ed.jumpToLine();
let editorDoc = ed.container.contentDocument;
let lineInput = editorDoc.querySelector("input");
lineInput.value = inputLine;
EventUtils.synthesizeKey("VK_RETURN", { }, editorDoc.defaultView);
// CodeMirror lines and columns are 0-based, Scratchpad UI is 1-based.
ch(ed.getCursor(), expectCursor, "jumpToLine " + inputLine + " expects cursor " + expectCursor.toSource());
}
function test() {
waitForExplicitFinish();
setup((ed, win) => {
let textLines = [
"// line 1",
"// line 2",
"// line 3",
"// line 4",
"// line 5",
""];
ed.setText(textLines.join("\n"));
waitForFocus(function () {
let testVectors = [
// Various useless inputs go to line 0, column 0 or do nothing.
["",
{line:0, ch:0}],
[":",
{line:0, ch:0}],
[" ",
{line:0, ch:0}],
[" : ",
{line:0, ch:0}],
["a:b",
{line:0, ch:0}],
["LINE:COLUMN",
{line:0, ch:0}],
["-1",
{line:0, ch:0}],
[":-1",
{line:0, ch:0}],
["-1:-1",
{line:0, ch:0}],
["0",
{line:0, ch:0}],
[":0",
{line:0, ch:0}],
["0:0",
{line:0, ch:0}],
// Starting here expect data needs to get updated for length changes to
// "textLines" above.
// Just jump to line
["1",
{line:0, ch:0}],
// Jump to second character in line
["1:2",
{line:0, ch:1}],
// Jump to last character on line
["1:9",
{line:0, ch:8}],
// Jump just after last character on line (end of line)
["1:10",
{line:0, ch:9}],
// Jump one character past end of line (gets clamped to end of line)
["1:11",
{line:0, ch:9}],
["2",
{line:1, ch:0}],
["2:2",
{line:1, ch:1}],
["2:10",
{line:1, ch:9}],
["2:11",
{line:1, ch:10}],
["2:12",
{line:1, ch:10}],
["3",
{line:2, ch:0}],
["3:2",
{line:2, ch:1}],
["3:11",
{line:2, ch:10}],
["3:12",
{line:2, ch:11}],
["3:13",
{line:2, ch:11}],
["4",
{line:3, ch:0}],
["4:2",
{line:3, ch:1}],
["4:12",
{line:3, ch:11}],
["4:13",
{line:3, ch:12}],
["4:14",
{line:3, ch:12}],
["5",
{line:4, ch:0}],
["5:2",
{line:4, ch:1}],
["5:13",
{line:4, ch:12}],
["5:14",
{line:4, ch:13}],
["5:15",
{line:4, ch:13}],
// One line beyond last newline in editor text:
["6",
{line:5, ch:0}],
["6:2",
{line:5, ch:0}],
// Two line beyond last newline in editor text (gets clamped):
["7",
{line:5, ch:0}],
["7:2",
{line:5, ch:0}]
];
testVectors.forEach(function (vector) {
testJumpToLine(ed, vector[0], vector[1]);
});
teardown(ed, win);
});
});
}

View File

@ -5,53 +5,47 @@
// This test makes sure that the style editor does not store any
// content CSS files in the permanent cache when opened from PB mode.
let gUI;
function test() {
waitForExplicitFinish();
let windowsToClose = [];
let gUI;
let testURI = 'http://' + TEST_HOST + '/browser/browser/devtools/styleeditor/test/test_private.html';
function checkCache() {
checkDiskCacheFor(TEST_HOST, function() {
gUI = null;
finish();
});
}
info("Opening a new private window");
let win = OpenBrowserWindow({private: true});
win.addEventListener("load", function onLoad() {
win.removeEventListener("load", onLoad, false);
executeSoon(startTest);
}, false);
function doTest(aWindow) {
aWindow.gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
aWindow.gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
function startTest() {
win.gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
win.gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
info("Clearing the browser cache");
cache.clear();
openStyleEditorInWindow(aWindow, function(panel) {
info("Opening the style editor in the private window");
openStyleEditorInWindow(win, function(panel) {
gUI = panel.UI;
gUI.on("editor-added", onEditorAdded);
});
}, true);
aWindow.gBrowser.selectedBrowser.loadURI(testURI);
info("Loading the test URL in the new private window");
win.content.location = testURI;
}
function onEditorAdded(aEvent, aEditor) {
info("The style editor is ready")
aEditor.getSourceEditor().then(checkCache);
}
function testOnWindow(options, callback) {
let win = OpenBrowserWindow(options);
win.addEventListener("load", function onLoad() {
win.removeEventListener("load", onLoad, false);
windowsToClose.push(win);
executeSoon(function() callback(win));
}, false);
};
registerCleanupFunction(function() {
windowsToClose.forEach(function(win) {
function checkCache() {
checkDiskCacheFor(TEST_HOST, function() {
win.close();
win = null;
gUI = null;
finish();
});
});
testOnWindow({private: true}, function(win) {
doTest(win);
});
}
}

View File

@ -272,10 +272,18 @@ browser.jar:
skin/classic/browser/devtools/debugger-toggleBreakpoints@2x.png (../shared/devtools/images/debugger-toggleBreakpoints@2x.png)
skin/classic/browser/devtools/tracer-icon.png (../shared/devtools/images/tracer-icon.png)
skin/classic/browser/devtools/tracer-icon@2x.png (../shared/devtools/images/tracer-icon@2x.png)
skin/classic/browser/devtools/responsive-se-resizer.png (../shared/devtools/images/responsive-se-resizer.png)
skin/classic/browser/devtools/responsive-vertical-resizer.png (../shared/devtools/images/responsive-vertical-resizer.png)
skin/classic/browser/devtools/responsive-horizontal-resizer.png (../shared/devtools/images/responsive-horizontal-resizer.png)
skin/classic/browser/devtools/responsive-background.png (../shared/devtools/images/responsive-background.png)
skin/classic/browser/devtools/responsive-se-resizer.png (../shared/devtools/images/responsivemode/responsive-se-resizer.png)
skin/classic/browser/devtools/responsive-se-resizer@2x.png (../shared/devtools/images/responsivemode/responsive-se-resizer@2x.png)
skin/classic/browser/devtools/responsive-vertical-resizer.png (../shared/devtools/images/responsivemode/responsive-vertical-resizer.png)
skin/classic/browser/devtools/responsive-vertical-resizer@2x.png (../shared/devtools/images/responsivemode/responsive-vertical-resizer@2x.png)
skin/classic/browser/devtools/responsive-horizontal-resizer.png (../shared/devtools/images/responsivemode/responsive-horizontal-resizer.png)
skin/classic/browser/devtools/responsive-horizontal-resizer@2x.png (../shared/devtools/images/responsivemode/responsive-horizontal-resizer@2x.png)
skin/classic/browser/devtools/responsiveui-rotate.png (../shared/devtools/images/responsivemode/responsiveui-rotate.png)
skin/classic/browser/devtools/responsiveui-rotate@2x.png (../shared/devtools/images/responsivemode/responsiveui-rotate@2x.png)
skin/classic/browser/devtools/responsiveui-touch.png (../shared/devtools/images/responsivemode/responsiveui-touch.png)
skin/classic/browser/devtools/responsiveui-touch@2x.png (../shared/devtools/images/responsivemode/responsiveui-touch@2x.png)
skin/classic/browser/devtools/responsiveui-screenshot.png (../shared/devtools/images/responsivemode/responsiveui-screenshot.png)
skin/classic/browser/devtools/responsiveui-screenshot@2x.png (../shared/devtools/images/responsivemode/responsiveui-screenshot@2x.png)
skin/classic/browser/devtools/toggle-tools.png (../shared/devtools/images/toggle-tools.png)
skin/classic/browser/devtools/dock-bottom@2x.png (../shared/devtools/images/dock-bottom@2x.png)
skin/classic/browser/devtools/dock-side@2x.png (../shared/devtools/images/dock-side@2x.png)
@ -309,9 +317,6 @@ browser.jar:
skin/classic/browser/devtools/font-inspector.css (../shared/devtools/font-inspector.css)
skin/classic/browser/devtools/computedview.css (../shared/devtools/computedview.css)
skin/classic/browser/devtools/arrow-e.png (../shared/devtools/images/arrow-e.png)
skin/classic/browser/devtools/responsiveui-rotate.png (../shared/devtools/responsiveui-rotate.png)
skin/classic/browser/devtools/responsiveui-touch.png (../shared/devtools/responsiveui-touch.png)
skin/classic/browser/devtools/responsiveui-screenshot.png (../shared/devtools/responsiveui-screenshot.png)
skin/classic/browser/devtools/projecteditor/projecteditor.css (../shared/devtools/projecteditor/projecteditor.css)
skin/classic/browser/devtools/projecteditor/file-icons-sheet@2x.png (../shared/devtools/projecteditor/file-icons-sheet@2x.png)
skin/classic/browser/devtools/app-manager/connection-footer.css (../shared/devtools/app-manager/connection-footer.css)

View File

@ -4,6 +4,14 @@
%include ../../../shared/incontentprefs/preferences.css
tab[selected] {
/* Override styles for tab[selected] from
toolkit/themes/linux/global/tabbox.css */
margin-bottom: 0;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
button > .button-box,
menulist > .menulist-label-box {
-moz-appearance: none;

View File

@ -392,10 +392,18 @@ browser.jar:
skin/classic/browser/devtools/tracer-icon@2x.png (../shared/devtools/images/tracer-icon@2x.png)
skin/classic/browser/devtools/floating-scrollbars.css (devtools/floating-scrollbars.css)
skin/classic/browser/devtools/floating-scrollbars-light.css (devtools/floating-scrollbars-light.css)
skin/classic/browser/devtools/responsive-se-resizer.png (../shared/devtools/images/responsive-se-resizer.png)
skin/classic/browser/devtools/responsive-vertical-resizer.png (../shared/devtools/images/responsive-vertical-resizer.png)
skin/classic/browser/devtools/responsive-horizontal-resizer.png (../shared/devtools/images/responsive-horizontal-resizer.png)
skin/classic/browser/devtools/responsive-background.png (../shared/devtools/images/responsive-background.png)
skin/classic/browser/devtools/responsive-se-resizer.png (../shared/devtools/images/responsivemode/responsive-se-resizer.png)
skin/classic/browser/devtools/responsive-se-resizer@2x.png (../shared/devtools/images/responsivemode/responsive-se-resizer@2x.png)
skin/classic/browser/devtools/responsive-vertical-resizer.png (../shared/devtools/images/responsivemode/responsive-vertical-resizer.png)
skin/classic/browser/devtools/responsive-vertical-resizer@2x.png (../shared/devtools/images/responsivemode/responsive-vertical-resizer@2x.png)
skin/classic/browser/devtools/responsive-horizontal-resizer.png (../shared/devtools/images/responsivemode/responsive-horizontal-resizer.png)
skin/classic/browser/devtools/responsive-horizontal-resizer@2x.png (../shared/devtools/images/responsivemode/responsive-horizontal-resizer@2x.png)
skin/classic/browser/devtools/responsiveui-rotate.png (../shared/devtools/images/responsivemode/responsiveui-rotate.png)
skin/classic/browser/devtools/responsiveui-rotate@2x.png (../shared/devtools/images/responsivemode/responsiveui-rotate@2x.png)
skin/classic/browser/devtools/responsiveui-touch.png (../shared/devtools/images/responsivemode/responsiveui-touch.png)
skin/classic/browser/devtools/responsiveui-touch@2x.png (../shared/devtools/images/responsivemode/responsiveui-touch@2x.png)
skin/classic/browser/devtools/responsiveui-screenshot.png (../shared/devtools/images/responsivemode/responsiveui-screenshot.png)
skin/classic/browser/devtools/responsiveui-screenshot@2x.png (../shared/devtools/images/responsivemode/responsiveui-screenshot@2x.png)
skin/classic/browser/devtools/toggle-tools.png (../shared/devtools/images/toggle-tools.png)
skin/classic/browser/devtools/dock-bottom@2x.png (../shared/devtools/images/dock-bottom@2x.png)
skin/classic/browser/devtools/dock-side@2x.png (../shared/devtools/images/dock-side@2x.png)
@ -427,9 +435,6 @@ browser.jar:
skin/classic/browser/devtools/font-inspector.css (../shared/devtools/font-inspector.css)
skin/classic/browser/devtools/computedview.css (../shared/devtools/computedview.css)
skin/classic/browser/devtools/arrow-e.png (../shared/devtools/images/arrow-e.png)
skin/classic/browser/devtools/responsiveui-rotate.png (../shared/devtools/responsiveui-rotate.png)
skin/classic/browser/devtools/responsiveui-touch.png (../shared/devtools/responsiveui-touch.png)
skin/classic/browser/devtools/responsiveui-screenshot.png (../shared/devtools/responsiveui-screenshot.png)
skin/classic/browser/devtools/projecteditor/projecteditor.css (../shared/devtools/projecteditor/projecteditor.css)
skin/classic/browser/devtools/projecteditor/file-icons-sheet@2x.png (../shared/devtools/projecteditor/file-icons-sheet@2x.png)
skin/classic/browser/devtools/app-manager/connection-footer.css (../shared/devtools/app-manager/connection-footer.css)

View File

@ -4,6 +4,20 @@
%include ../../../shared/incontentprefs/preferences.css
prefpane .groupbox-title {
background: none;
margin-bottom: 0;
}
tabs {
padding-right: 0;
padding-left: 0;
}
tab[selected] {
text-shadow: none;
}
menulist:not([editable="true"]) > menupopup > menuitem[checked="true"]::before,
menulist:not([editable="true"]) > menupopup > menuitem[selected="true"]::before {
display: none;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 256 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 339 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 237 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 205 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 245 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 438 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 303 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 531 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 470 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 927 B

View File

@ -7,7 +7,7 @@
/* Responsive Mode */
.browserContainer[responsivemode] {
background: #222 url("chrome://browser/skin/devtools/responsive-background.png");
background-color: #222;
padding: 0 20px 20px 20px;
}
@ -43,6 +43,11 @@
color: inherit;
}
.devtools-responsiveui-toolbarbutton > .toolbarbutton-icon {
width: 16px;
height: 16px;
}
.devtools-responsiveui-toolbarbutton > .toolbarbutton-menubutton-button {
-moz-box-orient: horizontal;
}
@ -135,6 +140,16 @@
list-style-image: url("chrome://browser/skin/devtools/responsiveui-rotate.png");
}
@media (min-resolution: 2dppx) {
.devtools-responsiveui-close {
list-style-image: url("chrome://browser/skin/devtools/close@2x.png");
}
.devtools-responsiveui-rotate {
list-style-image: url("chrome://browser/skin/devtools/responsiveui-rotate@2x.png");
}
}
.devtools-responsiveui-touch {
list-style-image: url("chrome://browser/skin/devtools/responsiveui-touch.png");
-moz-image-region: rect(0px,16px,16px,0px);
@ -144,15 +159,33 @@
-moz-image-region: rect(0px,32px,16px,16px);
}
@media (min-resolution: 2dppx) {
.devtools-responsiveui-touch {
list-style-image: url("chrome://browser/skin/devtools/responsiveui-touch@2x.png");
-moz-image-region: rect(0px,32px,32px,0px);
}
.devtools-responsiveui-touch[checked] {
-moz-image-region: rect(0px,64px,32px,32px);
}
}
.devtools-responsiveui-screenshot {
list-style-image: url("chrome://browser/skin/devtools/responsiveui-screenshot.png");
}
@media (min-resolution: 2dppx) {
.devtools-responsiveui-screenshot {
list-style-image: url("chrome://browser/skin/devtools/responsiveui-screenshot@2x.png");
}
}
.devtools-responsiveui-resizebarV {
width: 7px;
height: 24px;
cursor: ew-resize;
transform: translate(12px, -12px);
background-size: cover;
background-image: url("chrome://browser/skin/devtools/responsive-vertical-resizer.png");
}
@ -161,6 +194,7 @@
height: 7px;
cursor: ns-resize;
transform: translate(-12px, 12px);
background-size: cover;
background-image: url("chrome://browser/skin/devtools/responsive-horizontal-resizer.png");
}
@ -169,5 +203,20 @@
height: 16px;
cursor: se-resize;
transform: translate(12px, 12px);
background-size: cover;
background-image: url("chrome://browser/skin/devtools/responsive-se-resizer.png");
}
@media (min-resolution: 2dppx) {
.devtools-responsiveui-resizebarV {
background-image: url("chrome://browser/skin/devtools/responsive-vertical-resizer@2x.png");
}
.devtools-responsiveui-resizebarH {
background-image: url("chrome://browser/skin/devtools/responsive-horizontal-resizer@2x.png");
}
.devtools-responsiveui-resizehandle {
background-image: url("chrome://browser/skin/devtools/responsive-se-resizer@2x.png");
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 498 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 528 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 834 B

View File

@ -12,7 +12,7 @@
page {
-moz-appearance: none;
background-image: linear-gradient(#FFFFFF, #EDEDED 100px);
background-color: white;
}
* {
@ -84,10 +84,9 @@ tabpanels {
tabs {
-moz-margin-start: 60px;
margin-bottom: 15px;
border-top: 2px solid;
border-bottom: 2px solid;
-moz-border-top-colors: #BBBBBB #F9F9F9;
-moz-border-bottom-colors: #F9F9F9 #BBBBBB;
border-top: 1px solid #c1c1c1;
border-bottom: 1px solid #c1c1c1;
background-color: #fbfbfb;
}
.tabs-left,
@ -98,38 +97,26 @@ tabs {
tab {
-moz-appearance: none;
margin-top: 0;
padding: 0;
-moz-margin-end: 30px;
min-height: 60px;
background-color: transparent;
padding: 0 20px;
min-height: 44px;
color: #424f5a;
background-color: #fbfbfb;
border-width: 0;
border-bottom: 3px solid transparent;
transition: background-color 50ms ease 0s;
}
tab:hover {
background-color: #ebebeb;
}
tab[selected] {
border-bottom-color: #FF9500;
background-color: #ebebeb;
box-shadow: inset 0 -4px 0 0 #ff9500;
}
.tab-text {
font-size: 1.3rem;
line-height: 22px;
color: #333333;
border: 1px solid transparent;
border-radius: 5px;
}
tab:not([selected]):hover > .tab-middle > .tab-text {
background-color: rgba(255,255,255,0.5);
border-color: #FFFFFF;
}
tab:not([selected]):hover:active > .tab-middle > .tab-text {
background-color: rgba(0,0,0,0.03);
}
tab[selected] > .tab-middle > .tab-text {
font-weight: bold;
color: #424E5A;
}
/* buttons and menulists */

View File

@ -310,10 +310,18 @@ browser.jar:
skin/classic/browser/devtools/debugger-toggleBreakpoints@2x.png (../shared/devtools/images/debugger-toggleBreakpoints@2x.png)
skin/classic/browser/devtools/tracer-icon.png (../shared/devtools/images/tracer-icon.png)
skin/classic/browser/devtools/tracer-icon@2x.png (../shared/devtools/images/tracer-icon@2x.png)
skin/classic/browser/devtools/responsive-se-resizer.png (../shared/devtools/images/responsive-se-resizer.png)
skin/classic/browser/devtools/responsive-vertical-resizer.png (../shared/devtools/images/responsive-vertical-resizer.png)
skin/classic/browser/devtools/responsive-horizontal-resizer.png (../shared/devtools/images/responsive-horizontal-resizer.png)
skin/classic/browser/devtools/responsive-background.png (../shared/devtools/images/responsive-background.png)
skin/classic/browser/devtools/responsive-se-resizer.png (../shared/devtools/images/responsivemode/responsive-se-resizer.png)
skin/classic/browser/devtools/responsive-se-resizer@2x.png (../shared/devtools/images/responsivemode/responsive-se-resizer@2x.png)
skin/classic/browser/devtools/responsive-vertical-resizer.png (../shared/devtools/images/responsivemode/responsive-vertical-resizer.png)
skin/classic/browser/devtools/responsive-vertical-resizer@2x.png (../shared/devtools/images/responsivemode/responsive-vertical-resizer@2x.png)
skin/classic/browser/devtools/responsive-horizontal-resizer.png (../shared/devtools/images/responsivemode/responsive-horizontal-resizer.png)
skin/classic/browser/devtools/responsive-horizontal-resizer@2x.png (../shared/devtools/images/responsivemode/responsive-horizontal-resizer@2x.png)
skin/classic/browser/devtools/responsiveui-rotate.png (../shared/devtools/images/responsivemode/responsiveui-rotate.png)
skin/classic/browser/devtools/responsiveui-rotate@2x.png (../shared/devtools/images/responsivemode/responsiveui-rotate@2x.png)
skin/classic/browser/devtools/responsiveui-touch.png (../shared/devtools/images/responsivemode/responsiveui-touch.png)
skin/classic/browser/devtools/responsiveui-touch@2x.png (../shared/devtools/images/responsivemode/responsiveui-touch@2x.png)
skin/classic/browser/devtools/responsiveui-screenshot.png (../shared/devtools/images/responsivemode/responsiveui-screenshot.png)
skin/classic/browser/devtools/responsiveui-screenshot@2x.png (../shared/devtools/images/responsivemode/responsiveui-screenshot@2x.png)
skin/classic/browser/devtools/toggle-tools.png (../shared/devtools/images/toggle-tools.png)
skin/classic/browser/devtools/dock-bottom@2x.png (../shared/devtools/images/dock-bottom@2x.png)
skin/classic/browser/devtools/dock-side@2x.png (../shared/devtools/images/dock-side@2x.png)
@ -346,9 +354,6 @@ browser.jar:
skin/classic/browser/devtools/font-inspector.css (../shared/devtools/font-inspector.css)
skin/classic/browser/devtools/computedview.css (../shared/devtools/computedview.css)
skin/classic/browser/devtools/arrow-e.png (../shared/devtools/images/arrow-e.png)
skin/classic/browser/devtools/responsiveui-rotate.png (../shared/devtools/responsiveui-rotate.png)
skin/classic/browser/devtools/responsiveui-touch.png (../shared/devtools/responsiveui-touch.png)
skin/classic/browser/devtools/responsiveui-screenshot.png (../shared/devtools/responsiveui-screenshot.png)
skin/classic/browser/devtools/projecteditor/projecteditor.css (../shared/devtools/projecteditor/projecteditor.css)
skin/classic/browser/devtools/projecteditor/file-icons-sheet@2x.png (../shared/devtools/projecteditor/file-icons-sheet@2x.png)
skin/classic/browser/devtools/app-manager/connection-footer.css (../shared/devtools/app-manager/connection-footer.css)
@ -705,10 +710,18 @@ browser.jar:
skin/classic/aero/browser/devtools/debugger-toggleBreakpoints@2x.png (../shared/devtools/images/debugger-toggleBreakpoints@2x.png)
skin/classic/aero/browser/devtools/tracer-icon.png (../shared/devtools/images/tracer-icon.png)
skin/classic/aero/browser/devtools/tracer-icon@2x.png (../shared/devtools/images/tracer-icon@2x.png)
skin/classic/aero/browser/devtools/responsive-se-resizer.png (../shared/devtools/images/responsive-se-resizer.png)
skin/classic/aero/browser/devtools/responsive-vertical-resizer.png (../shared/devtools/images/responsive-vertical-resizer.png)
skin/classic/aero/browser/devtools/responsive-horizontal-resizer.png (../shared/devtools/images/responsive-horizontal-resizer.png)
skin/classic/aero/browser/devtools/responsive-background.png (../shared/devtools/images/responsive-background.png)
skin/classic/aero/browser/devtools/responsive-se-resizer.png (../shared/devtools/images/responsivemode/responsive-se-resizer.png)
skin/classic/aero/browser/devtools/responsive-se-resizer@2x.png (../shared/devtools/images/responsivemode/responsive-se-resizer@2x.png)
skin/classic/aero/browser/devtools/responsive-vertical-resizer.png (../shared/devtools/images/responsivemode/responsive-vertical-resizer.png)
skin/classic/aero/browser/devtools/responsive-vertical-resizer@2x.png (../shared/devtools/images/responsivemode/responsive-vertical-resizer@2x.png)
skin/classic/aero/browser/devtools/responsive-horizontal-resizer.png (../shared/devtools/images/responsivemode/responsive-horizontal-resizer.png)
skin/classic/aero/browser/devtools/responsive-horizontal-resizer@2x.png (../shared/devtools/images/responsivemode/responsive-horizontal-resizer@2x.png)
skin/classic/aero/browser/devtools/responsiveui-rotate.png (../shared/devtools/images/responsivemode/responsiveui-rotate.png)
skin/classic/aero/browser/devtools/responsiveui-rotate@2x.png (../shared/devtools/images/responsivemode/responsiveui-rotate@2x.png)
skin/classic/aero/browser/devtools/responsiveui-touch.png (../shared/devtools/images/responsivemode/responsiveui-touch.png)
skin/classic/aero/browser/devtools/responsiveui-touch@2x.png (../shared/devtools/images/responsivemode/responsiveui-touch@2x.png)
skin/classic/aero/browser/devtools/responsiveui-screenshot.png (../shared/devtools/images/responsivemode/responsiveui-screenshot.png)
skin/classic/aero/browser/devtools/responsiveui-screenshot@2x.png (../shared/devtools/images/responsivemode/responsiveui-screenshot@2x.png)
skin/classic/aero/browser/devtools/toggle-tools.png (../shared/devtools/images/toggle-tools.png)
skin/classic/aero/browser/devtools/dock-bottom@2x.png (../shared/devtools/images/dock-bottom@2x.png)
skin/classic/aero/browser/devtools/dock-side@2x.png (../shared/devtools/images/dock-side@2x.png)
@ -741,9 +754,6 @@ browser.jar:
skin/classic/aero/browser/devtools/font-inspector.css (../shared/devtools/font-inspector.css)
skin/classic/aero/browser/devtools/computedview.css (../shared/devtools/computedview.css)
skin/classic/aero/browser/devtools/arrow-e.png (../shared/devtools/images/arrow-e.png)
skin/classic/aero/browser/devtools/responsiveui-rotate.png (../shared/devtools/responsiveui-rotate.png)
skin/classic/aero/browser/devtools/responsiveui-touch.png (../shared/devtools/responsiveui-touch.png)
skin/classic/aero/browser/devtools/responsiveui-screenshot.png (../shared/devtools/responsiveui-screenshot.png)
skin/classic/aero/browser/devtools/projecteditor/projecteditor.css (../shared/devtools/projecteditor/projecteditor.css)
skin/classic/aero/browser/devtools/projecteditor/file-icons-sheet@2x.png (../shared/devtools/projecteditor/file-icons-sheet@2x.png)
skin/classic/aero/browser/devtools/app-manager/connection-footer.css (../shared/devtools/app-manager/connection-footer.css)

View File

@ -4,6 +4,10 @@
%include ../../../shared/incontentprefs/preferences.css
caption {
background-color: transparent;
}
menulist:not([editable="true"]) > .menulist-dropmarker {
margin-top: 1px;
margin-bottom: 1px;

View File

@ -1039,7 +1039,7 @@ nsScriptSecurityManager::CanCreateWrapper(JSContext *cx,
}
// We give remote-XUL whitelisted domains a free pass here. See bug 932906.
if (!xpc::AllowXBLScope(js::GetContextCompartment(cx)))
if (!xpc::AllowContentXBLScope(js::GetContextCompartment(cx)))
{
return NS_OK;
}

View File

@ -188,7 +188,7 @@ public:
static bool IsCallerChrome();
static bool ThreadsafeIsCallerChrome();
static bool IsCallerXBL();
static bool IsCallerContentXBL();
static bool IsImageSrcSetDisabled();

View File

@ -696,7 +696,8 @@ nsCSPParser::sourceList(nsTArray<nsCSPBaseSrc*>& outSrcs)
}
// Otherwise, we ignore 'none' and report a warning
else {
const char16_t* params[] = { NS_ConvertUTF8toUTF16(CSP_EnumToKeyword(CSP_NONE)).get() };
NS_ConvertUTF8toUTF16 unicodeNone(CSP_EnumToKeyword(CSP_NONE));
const char16_t* params[] = { unicodeNone.get() };
logWarningErrorToConsole(nsIScriptError::warningFlag, "ignoringUnknownOption",
params, ArrayLength(params));
}
@ -887,7 +888,8 @@ nsCSPParser::parseContentSecurityPolicy(const nsAString& aPolicyString,
nsAutoCString prePath;
nsresult rv = aSelfURI->GetPrePath(prePath);
NS_ENSURE_SUCCESS(rv, policy);
const char16_t* params[] = { NS_ConvertUTF8toUTF16(prePath).get() };
NS_ConvertUTF8toUTF16 unicodePrePath(prePath);
const char16_t* params[] = { unicodePrePath.get() };
parser.logWarningErrorToConsole(nsIScriptError::warningFlag, "reportURInotInReportOnlyHeader",
params, ArrayLength(params));
}

View File

@ -367,7 +367,8 @@ CSPService::AsyncOnChannelRedirect(nsIChannel *oldChannel,
// to enforce the load policy if it redirects again, so we stop it now.
nsAutoCString newUriSpec;
rv = newUri->GetSpec(newUriSpec);
const char16_t *formatParams[] = { NS_ConvertUTF8toUTF16(newUriSpec).get() };
NS_ConvertUTF8toUTF16 unicodeSpec(newUriSpec);
const char16_t *formatParams[] = { unicodeSpec.get() };
if (NS_SUCCEEDED(rv)) {
nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
NS_LITERAL_CSTRING("Redirect Error"), nullptr,

View File

@ -1714,7 +1714,7 @@ nsContentUtils::ThreadsafeIsCallerChrome()
}
bool
nsContentUtils::IsCallerXBL()
nsContentUtils::IsCallerContentXBL()
{
JSContext *cx = GetCurrentJSContext();
if (!cx)
@ -1724,12 +1724,12 @@ nsContentUtils::IsCallerXBL()
// For remote XUL, we run XBL in the XUL scope. Given that we care about
// compat and not security for remote XUL, just always claim to be XBL.
if (!xpc::AllowXBLScope(c)) {
if (!xpc::AllowContentXBLScope(c)) {
MOZ_ASSERT(nsContentUtils::AllowXULXBLForPrincipal(xpc::GetCompartmentPrincipal(c)));
return true;
}
return xpc::IsXBLScope(c);
return xpc::IsContentXBLScope(c);
}
@ -5585,7 +5585,7 @@ nsContentTypeParser::GetParameter(const char* aParameterName, nsAString& aResult
bool
nsContentUtils::CanAccessNativeAnon()
{
return IsCallerChrome() || IsCallerXBL();
return IsCallerChrome() || IsCallerContentXBL();
}
/* static */ nsresult

View File

@ -2660,7 +2660,7 @@ nsINode::WrapObject(JSContext *aCx)
JS::Rooted<JSObject*> obj(aCx, WrapNode(aCx));
MOZ_ASSERT_IF(ChromeOnlyAccess(),
xpc::IsInXBLScope(obj) || !xpc::UseXBLScope(js::GetObjectCompartment(obj)));
xpc::IsInContentXBLScope(obj) || !xpc::UseContentXBLScope(js::GetObjectCompartment(obj)));
return obj;
}

View File

@ -2650,7 +2650,7 @@ nsObjectLoadingContent::ScriptRequestPluginInstance(JSContext* aCx,
MOZ_ASSERT_IF(nsContentUtils::GetCurrentJSContext(),
aCx == nsContentUtils::GetCurrentJSContext());
bool callerIsContentJS = (!nsContentUtils::IsCallerChrome() &&
!nsContentUtils::IsCallerXBL() &&
!nsContentUtils::IsCallerContentXBL() &&
js::IsContextRunningJS(aCx));
nsCOMPtr<nsIContent> thisContent =

View File

@ -83,18 +83,21 @@ WebGLMemoryPressureObserver::Observe(nsISupports* aSubject,
if (!mContext->mCanLoseContextInForeground &&
ProcessPriorityManager::CurrentProcessIsForeground())
{
wantToLoseContext = false;
else if (!nsCRT::strcmp(aSomeData,
MOZ_UTF16("heap-minimize")))
} else if (!nsCRT::strcmp(aSomeData,
MOZ_UTF16("heap-minimize")))
{
wantToLoseContext = mContext->mLoseContextOnHeapMinimize;
}
if (wantToLoseContext)
if (wantToLoseContext) {
mContext->ForceLoseContext();
}
return NS_OK;
}
WebGLContextOptions::WebGLContextOptions()
: alpha(true), depth(true), stencil(false),
premultipliedAlpha(true), antialias(true),
@ -168,12 +171,12 @@ WebGLContext::WebGLContext()
WebGLMemoryTracker::AddWebGLContext(this);
mAllowRestore = true;
mAllowContextRestore = true;
mLastLossWasSimulated = false;
mContextLossTimerRunning = false;
mDrawSinceContextLossTimerSet = false;
mRunContextLossTimerAgain = false;
mContextRestorer = do_CreateInstance("@mozilla.org/timer;1");
mContextStatus = ContextNotLost;
mContextLostErrorSet = false;
mLoseContextOnHeapMinimize = false;
mCanLoseContextInForeground = true;
@ -571,11 +574,8 @@ WebGLContext::SetDimensions(int32_t width, int32_t height)
mResetLayer = true;
mOptionsFrozen = true;
mHasRobustness = gl->HasRobustness();
// increment the generation number
++mGeneration;
#if 0
if (mGeneration > 0) {
// XXX dispatch context lost event
@ -1115,6 +1115,96 @@ WebGLContext::DummyFramebufferOperation(const char *info)
ErrorInvalidFramebufferOperation("%s: incomplete framebuffer", info);
}
static bool
CheckContextLost(GLContext* gl, bool* out_isGuilty)
{
MOZ_ASSERT(gl);
MOZ_ASSERT(out_isGuilty);
bool isEGL = gl->GetContextType() == gl::GLContextType::EGL;
GLenum resetStatus = LOCAL_GL_NO_ERROR;
if (gl->HasRobustness()) {
gl->MakeCurrent();
resetStatus = gl->fGetGraphicsResetStatus();
} else if (isEGL) {
// Simulate a ARB_robustness guilty context loss for when we
// get an EGL_CONTEXT_LOST error. It may not actually be guilty,
// but we can't make any distinction.
if (!gl->MakeCurrent(true) && gl->IsContextLost()) {
resetStatus = LOCAL_GL_UNKNOWN_CONTEXT_RESET_ARB;
}
}
if (resetStatus == LOCAL_GL_NO_ERROR) {
*out_isGuilty = false;
return false;
}
// Assume guilty unless we find otherwise!
bool isGuilty = true;
switch (resetStatus) {
case LOCAL_GL_INNOCENT_CONTEXT_RESET_ARB:
// Either nothing wrong, or not our fault.
isGuilty = false;
break;
case LOCAL_GL_GUILTY_CONTEXT_RESET_ARB:
NS_WARNING("WebGL content on the page definitely caused the graphics"
" card to reset.");
break;
case LOCAL_GL_UNKNOWN_CONTEXT_RESET_ARB:
NS_WARNING("WebGL content on the page might have caused the graphics"
" card to reset");
// If we can't tell, assume guilty.
break;
default:
MOZ_ASSERT(false, "Unreachable.");
// If we do get here, let's pretend to be guilty as an escape plan.
break;
}
if (isGuilty) {
NS_WARNING("WebGL context on this page is considered guilty, and will"
" not be restored.");
}
*out_isGuilty = isGuilty;
return true;
}
bool
WebGLContext::TryToRestoreContext()
{
if (NS_FAILED(SetDimensions(mWidth, mHeight)))
return false;
return true;
}
class UpdateContextLossStatusTask : public nsRunnable
{
nsRefPtr<WebGLContext> mContext;
public:
UpdateContextLossStatusTask(WebGLContext* context)
: mContext(context)
{
}
NS_IMETHOD Run() {
mContext->UpdateContextLossStatus();
return NS_OK;
}
};
void
WebGLContext::EnqueueUpdateContextLossStatus()
{
nsCOMPtr<nsIRunnable> task = new UpdateContextLossStatusTask(this);
NS_DispatchToCurrentThread(task);
}
// We use this timer for many things. Here are the things that it is activated for:
// 1) If a script is using the MOZ_WEBGL_lose_context extension.
// 2) If we are using EGL and _NOT ANGLE_, we query periodically to see if the
@ -1130,137 +1220,124 @@ WebGLContext::DummyFramebufferOperation(const char *info)
// At a bare minimum, from context lost to context restores, it would take 3
// full timer iterations: detection, webglcontextlost, webglcontextrestored.
void
WebGLContext::RobustnessTimerCallback(nsITimer* timer)
WebGLContext::UpdateContextLossStatus()
{
TerminateContextLossTimer();
if (!mCanvasElement) {
// the canvas is gone. That happens when the page was closed before we got
// this timer event. In this case, there's nothing to do here, just don't crash.
return;
}
if (mContextStatus == ContextNotLost) {
// We don't know that we're lost, but we might be, so we need to
// check. If we're guilty, don't allow restores, though.
bool isGuilty = true;
MOZ_ASSERT(gl); // Shouldn't be missing gl if we're NotLost.
bool isContextLost = CheckContextLost(gl, &isGuilty);
if (isContextLost) {
if (isGuilty)
mAllowContextRestore = false;
ForceLoseContext();
}
// Fall through.
}
// If the context has been lost and we're waiting for it to be restored, do
// that now.
if (mContextStatus == ContextLostAwaitingEvent) {
bool defaultAction;
// The context has been lost and we haven't yet triggered the
// callback, so do that now.
bool useDefaultHandler;
nsContentUtils::DispatchTrustedEvent(mCanvasElement->OwnerDoc(),
static_cast<nsIDOMHTMLCanvasElement*>(mCanvasElement),
NS_LITERAL_STRING("webglcontextlost"),
true,
true,
&defaultAction);
&useDefaultHandler);
// We sent the callback, so we're just 'regular lost' now.
mContextStatus = ContextLost;
// If we're told to use the default handler, it means the script
// didn't bother to handle the event. In this case, we shouldn't
// auto-restore the context.
if (useDefaultHandler)
mAllowContextRestore = false;
// If the script didn't handle the event, we don't allow restores.
if (defaultAction)
mAllowRestore = false;
// Fall through.
}
// If the script handled the event and we are allowing restores, then
// mark it to be restored. Otherwise, leave it as context lost
// (unusable).
if (!defaultAction && mAllowRestore) {
ForceRestoreContext();
// Restart the timer so that it will be restored on the next
// callback.
SetupContextLossTimer();
} else {
if (mContextStatus == ContextLost) {
// Context is lost, and we've already sent the callback. We
// should try to restore the context if we're both allowed to,
// and supposed to.
// Are we allowed to restore the context?
if (!mAllowContextRestore)
return;
// If we're only simulated-lost, we shouldn't auto-restore, and
// instead we should wait for restoreContext() to be called.
if (mLastLossWasSimulated)
return;
ForceRestoreContext();
return;
}
if (mContextStatus == ContextLostAwaitingRestore) {
// Context is lost, but we should try to restore it.
if (!mAllowContextRestore) {
// We might decide this after thinking we'd be OK restoring
// the context, so downgrade.
mContextStatus = ContextLost;
}
} else if (mContextStatus == ContextLostAwaitingRestore) {
// Try to restore the context. If it fails, try again later.
if (NS_FAILED(SetDimensions(mWidth, mHeight))) {
SetupContextLossTimer();
return;
}
if (!TryToRestoreContext()) {
// Failed to restore. Try again later.
RunContextLossTimer();
return;
}
// Revival!
mContextStatus = ContextNotLost;
nsContentUtils::DispatchTrustedEvent(mCanvasElement->OwnerDoc(),
static_cast<nsIDOMHTMLCanvasElement*>(mCanvasElement),
NS_LITERAL_STRING("webglcontextrestored"),
true,
true);
// Set all flags back to the state they were in before the context was
// lost.
mEmitContextLostErrorOnce = true;
mAllowRestore = true;
}
MaybeRestoreContext();
return;
}
void
WebGLContext::MaybeRestoreContext()
{
// Don't try to handle it if we already know it's busted.
if (mContextStatus != ContextNotLost || gl == nullptr)
return;
bool isEGL = gl->GetContextType() == gl::GLContextType::EGL,
isANGLE = gl->IsANGLE();
GLContext::ContextResetARB resetStatus = GLContext::CONTEXT_NO_ERROR;
if (mHasRobustness) {
gl->MakeCurrent();
resetStatus = (GLContext::ContextResetARB) gl->fGetGraphicsResetStatus();
} else if (isEGL) {
// Simulate a ARB_robustness guilty context loss for when we
// get an EGL_CONTEXT_LOST error. It may not actually be guilty,
// but we can't make any distinction, so we must assume the worst
// case.
if (!gl->MakeCurrent(true) && gl->IsContextLost()) {
resetStatus = GLContext::CONTEXT_GUILTY_CONTEXT_RESET_ARB;
}
}
if (resetStatus != GLContext::CONTEXT_NO_ERROR) {
// It's already lost, but clean up after it and signal to JS that it is
// lost.
ForceLoseContext();
}
switch (resetStatus) {
case GLContext::CONTEXT_NO_ERROR:
// If there has been activity since the timer was set, it's possible
// that we did or are going to miss something, so clear this flag and
// run it again some time later.
if (mDrawSinceContextLossTimerSet)
SetupContextLossTimer();
break;
case GLContext::CONTEXT_GUILTY_CONTEXT_RESET_ARB:
NS_WARNING("WebGL content on the page caused the graphics card to reset; not restoring the context");
mAllowRestore = false;
break;
case GLContext::CONTEXT_INNOCENT_CONTEXT_RESET_ARB:
break;
case GLContext::CONTEXT_UNKNOWN_CONTEXT_RESET_ARB:
NS_WARNING("WebGL content on the page might have caused the graphics card to reset");
if (isEGL && isANGLE) {
// If we're using ANGLE, we ONLY get back UNKNOWN context resets, including for guilty contexts.
// This means that we can't restore it or risk restoring a guilty context. Should this ever change,
// we can get rid of the whole IsANGLE() junk from GLContext.h since, as of writing, this is the
// only use for it. See ANGLE issue 261.
mAllowRestore = false;
}
break;
}
}
void
WebGLContext::ForceLoseContext()
{
if (mContextStatus == ContextLostAwaitingEvent)
return;
printf_stderr("WebGL(%p)::ForceLoseContext\n", this);
MOZ_ASSERT(!IsContextLost());
mContextStatus = ContextLostAwaitingEvent;
// Queue up a task to restore the event.
SetupContextLossTimer();
mContextLostErrorSet = false;
mLastLossWasSimulated = false;
// Burn it all!
DestroyResourcesAndContext();
// Queue up a task, since we know the status changed.
EnqueueUpdateContextLossStatus();
}
void
WebGLContext::ForceRestoreContext()
{
printf_stderr("WebGL(%p)::ForceRestoreContext\n", this);
mContextStatus = ContextLostAwaitingRestore;
mAllowContextRestore = true; // Hey, you did say 'force'.
// Queue up a task, since we know the status changed.
EnqueueUpdateContextLossStatus();
}
void

View File

@ -202,9 +202,6 @@ public:
int32_t x, int32_t y, int32_t w, int32_t h)
{ return NS_ERROR_NOT_IMPLEMENTED; }
bool LoseContext();
bool RestoreContext();
void SynthesizeGLError(GLenum err);
void SynthesizeGLError(GLenum err, const char *fmt, ...);
@ -261,11 +258,14 @@ public:
bool MinCapabilityMode() const { return mMinCapability; }
void RobustnessTimerCallback(nsITimer* timer);
static void RobustnessTimerCallbackStatic(nsITimer* timer, void *thisPointer);
void SetupContextLossTimer();
void UpdateContextLossStatus();
void EnqueueUpdateContextLossStatus();
static void ContextLossCallbackStatic(nsITimer* timer, void* thisPointer);
void RunContextLossTimer();
void TerminateContextLossTimer();
bool TryToRestoreContext();
void AssertCachedBindings();
void AssertCachedState();
@ -666,8 +666,12 @@ public:
bool ValidateSamplerUniformSetter(const char* info,
WebGLUniformLocation *location,
GLint value);
void Viewport(GLint x, GLint y, GLsizei width, GLsizei height);
// -----------------------------------------------------------------------------
// WEBGL_lose_context
public:
void LoseContext();
void RestoreContext();
// -----------------------------------------------------------------------------
// Asynchronous Queries (WebGLContextAsyncQueries.cpp)
@ -869,7 +873,6 @@ protected:
bool mOptionsFrozen;
bool mMinCapability;
bool mDisableExtensions;
bool mHasRobustness;
bool mIsMesa;
bool mLoseContextOnHeapMinimize;
bool mCanLoseContextInForeground;
@ -1116,7 +1119,6 @@ protected:
GLenum type,
const GLvoid *data);
void MaybeRestoreContext();
void ForceLoseContext();
void ForceRestoreContext();
@ -1178,7 +1180,7 @@ protected:
GLint mStencilRefFront, mStencilRefBack;
GLuint mStencilValueMaskFront, mStencilValueMaskBack,
mStencilWriteMaskFront, mStencilWriteMaskBack;
mStencilWriteMaskFront, mStencilWriteMaskBack;
realGLboolean mColorWriteMask[4];
realGLboolean mDepthWriteMask;
GLfloat mColorClearValue[4];
@ -1192,9 +1194,10 @@ protected:
bool mAlreadyWarnedAboutViewportLargerThanDest;
nsCOMPtr<nsITimer> mContextRestorer;
bool mAllowRestore;
bool mAllowContextRestore;
bool mLastLossWasSimulated;
bool mContextLossTimerRunning;
bool mDrawSinceContextLossTimerSet;
bool mRunContextLossTimerAgain;
ContextStatus mContextStatus;
bool mContextLostErrorSet;

View File

@ -128,7 +128,7 @@ WebGLContext::DrawArrays(GLenum mode, GLint first, GLsizei count)
if (!DrawArrays_check(first, count, 1, "drawArrays"))
return;
SetupContextLossTimer();
RunContextLossTimer();
gl->fDrawArrays(mode, first, count);
Draw_cleanup();
@ -149,7 +149,7 @@ WebGLContext::DrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsiz
if (!DrawInstanced_check("drawArraysInstanced"))
return;
SetupContextLossTimer();
RunContextLossTimer();
gl->fDrawArraysInstanced(mode, first, count, primcount);
Draw_cleanup();
@ -296,7 +296,7 @@ WebGLContext::DrawElements(GLenum mode, GLsizei count, GLenum type,
return;
}
SetupContextLossTimer();
RunContextLossTimer();
if (gl->IsSupported(gl::GLFeature::draw_range_elements)) {
gl->fDrawRangeElements(mode, 0, upperBound,
@ -324,7 +324,7 @@ WebGLContext::DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type,
if (!DrawInstanced_check("drawElementsInstanced"))
return;
SetupContextLossTimer();
RunContextLossTimer();
gl->fDrawElementsInstanced(mode, count, type, reinterpret_cast<GLvoid*>(byteOffset), primcount);
Draw_cleanup();

View File

@ -3857,27 +3857,34 @@ WebGLContext::TexSubImage2D(GLenum target, GLint level,
WebGLTexelFormat::RGBA8, false);
}
bool
void
WebGLContext::LoseContext()
{
if (IsContextLost())
return false;
return ErrorInvalidOperation("loseContext: Context is already lost.");
ForceLoseContext();
return true;
mLastLossWasSimulated = true;
}
bool
void
WebGLContext::RestoreContext()
{
if (!IsContextLost() || !mAllowRestore) {
return false;
if (!IsContextLost())
return ErrorInvalidOperation("restoreContext: Context is not lost.");
if (!mLastLossWasSimulated) {
return ErrorInvalidOperation("restoreContext: Context loss was not simulated."
" Cannot simulate restore.");
}
// If we're currently lost, and the last loss was simulated, then
// we're currently only simulated-lost, allowing us to call
// restoreContext().
if (!mAllowContextRestore)
return ErrorInvalidOperation("restoreContext: Context cannot be restored.");
ForceRestoreContext();
return true;
}
bool

View File

@ -8,33 +8,45 @@
using namespace mozilla;
/* static */ void
WebGLContext::RobustnessTimerCallbackStatic(nsITimer* timer, void *thisPointer) {
static_cast<WebGLContext*>(thisPointer)->RobustnessTimerCallback(timer);
WebGLContext::ContextLossCallbackStatic(nsITimer* timer, void* thisPointer)
{
(void)timer;
WebGLContext* context = static_cast<WebGLContext*>(thisPointer);
context->TerminateContextLossTimer();
context->UpdateContextLossStatus();
}
void
WebGLContext::SetupContextLossTimer() {
WebGLContext::RunContextLossTimer()
{
// If the timer was already running, don't restart it here. Instead,
// wait until the previous call is done, then fire it one more time.
// This is an optimization to prevent unnecessary cross-communication
// between threads.
// This is an optimization to prevent unnecessary
// cross-communication between threads.
if (mContextLossTimerRunning) {
mDrawSinceContextLossTimerSet = true;
mRunContextLossTimerAgain = true;
return;
}
mContextRestorer->InitWithFuncCallback(RobustnessTimerCallbackStatic,
static_cast<void*>(this),
1000,
nsITimer::TYPE_ONE_SHOT);
mContextRestorer->InitWithFuncCallback(ContextLossCallbackStatic,
static_cast<void*>(this),
1000,
nsITimer::TYPE_ONE_SHOT);
mContextLossTimerRunning = true;
mDrawSinceContextLossTimerSet = false;
mRunContextLossTimerAgain = false;
}
void
WebGLContext::TerminateContextLossTimer() {
if (mContextLossTimerRunning) {
mContextRestorer->Cancel();
mContextLossTimerRunning = false;
WebGLContext::TerminateContextLossTimer()
{
if (!mContextLossTimerRunning)
return;
mContextRestorer->Cancel();
mContextLossTimerRunning = false;
if (mRunContextLossTimerAgain) {
RunContextLossTimer();
}
}

View File

@ -21,15 +21,13 @@ WebGLExtensionLoseContext::~WebGLExtensionLoseContext()
void
WebGLExtensionLoseContext::LoseContext()
{
if (!mContext->LoseContext())
mContext->mWebGLError = LOCAL_GL_INVALID_OPERATION;
mContext->LoseContext();
}
void
void
WebGLExtensionLoseContext::RestoreContext()
{
if (!mContext->RestoreContext())
mContext->mWebGLError = LOCAL_GL_INVALID_OPERATION;
mContext->RestoreContext();
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionLoseContext)

View File

@ -99,7 +99,7 @@ function testLosingAndRestoringContext()
// restore the context after this event has exited.
setTimeout(function() {
shouldGenerateGLError(gl, gl.NO_ERROR, "extension.restoreContext()");
// The context should still be lost. It will not get restored until the
// The context should still be lost. It will not get restored until the
// webglrestorecontext event is fired.
shouldBeTrue("gl.isContextLost()");
shouldBe("gl.getError()", "gl.NO_ERROR");

View File

@ -3064,6 +3064,14 @@ void HTMLMediaElement::UpdateReadyStateForData(MediaDecoderOwner::NextFrameStatu
return;
}
// Section 2.4.3.1 of the Media Source Extensions spec requires
// changing to HAVE_METADATA when seeking into an unbuffered
// range.
if (aNextFrame == MediaDecoderOwner::NEXT_FRAME_WAIT_FOR_MSE_DATA) {
ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_METADATA);
return;
}
if (mReadyState > nsIDOMHTMLMediaElement::HAVE_METADATA &&
mDownloadSuspendedByCache &&
mDecoder &&

View File

@ -119,6 +119,9 @@ public:
NEXT_FRAME_UNAVAILABLE_BUFFERING,
// The next frame of audio/video is unavailable for some other reasons
NEXT_FRAME_UNAVAILABLE,
// The next frame is unavailable due to waiting for more Media Source
// Extensions data to become available.
NEXT_FRAME_WAIT_FOR_MSE_DATA,
// Sentinel value
NEXT_FRAME_UNINITIALIZED
};

View File

@ -152,7 +152,6 @@ TEST(WebMWriter, Cluster)
EXPECT_TRUE(encodedBuf.Length() > 0);
encodedBuf.Clear();
uint64_t timestamp = 0;
// write the first I-Frame.
writer.AppendDummyFrame(EncodedFrame::VP8_I_FRAME, FIXED_DURATION);
// No data because the cluster is not closed.
@ -191,7 +190,6 @@ TEST(WebMWriter, FLUSH_NEEDED)
writer.SetVP8Metadata(width, height, displayWidth,
displayHeight, aTrackRate);
uint64_t timestamp = 0;
// write the first I-Frame.
writer.AppendDummyFrame(EncodedFrame::VP8_I_FRAME, FIXED_DURATION);

View File

@ -26,3 +26,5 @@ LOCAL_INCLUDES += [
]
FINAL_LIBRARY = 'xul-gtest'
FAIL_ON_WARNINGS = True

View File

@ -299,6 +299,7 @@ MediaSource::MediaSource(nsPIDOMWindow* aWindow)
, mDuration(UnspecifiedNaN<double>())
, mDecoder(nullptr)
, mReadyState(MediaSourceReadyState::Closed)
, mWaitForDataMonitor("MediaSource.WaitForData.Monitor")
{
mSourceBuffers = new SourceBufferList(this);
mActiveSourceBuffers = new SourceBufferList(this);
@ -395,6 +396,20 @@ MediaSource::NotifyEvicted(double aStart, double aEnd)
mSourceBuffers->Evict(aStart, aEnd);
}
void
MediaSource::WaitForData()
{
MonitorAutoLock lock(mWaitForDataMonitor);
lock.Wait();
}
void
MediaSource::NotifyGotData()
{
MonitorAutoLock lock(mWaitForDataMonitor);
lock.NotifyAll();
}
NS_IMPL_CYCLE_COLLECTION_INHERITED(MediaSource, DOMEventTargetHelper,
mSourceBuffers, mActiveSourceBuffers)

View File

@ -13,6 +13,7 @@
#include "mozilla/Attributes.h"
#include "mozilla/DOMEventTargetHelper.h"
#include "mozilla/dom/MediaSourceBinding.h"
#include "mozilla/Monitor.h"
#include "nsAutoPtr.h"
#include "nsCOMPtr.h"
#include "nsCycleCollectionNoteChild.h"
@ -89,6 +90,12 @@ public:
// that were evicted are provided.
void NotifyEvicted(double aStart, double aEnd);
// Block thread waiting for data to be appended to a SourceBuffer.
void WaitForData();
// Unblock threads waiting for data to be appended to a SourceBuffer.
void NotifyGotData();
private:
explicit MediaSource(nsPIDOMWindow* aWindow);
@ -106,6 +113,10 @@ private:
nsRefPtr<MediaSourceDecoder> mDecoder;
MediaSourceReadyState mReadyState;
// Monitor for waiting for when new data is appended to
// a Source Buffer.
Monitor mWaitForDataMonitor;
};
NS_DEFINE_STATIC_IID_ACCESSOR(MediaSource, MOZILLA_DOM_MEDIASOURCE_IMPLEMENTATION_IID)

View File

@ -130,6 +130,11 @@ public:
void InitializePendingDecoders();
bool IsShutdown() {
ReentrantMonitorAutoEnter decoderMon(mDecoder->GetReentrantMonitor());
return mDecoder->IsShutdown();
}
private:
bool MaybeSwitchVideoReaders(int64_t aTimeThreshold) {
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
@ -383,25 +388,60 @@ MediaSourceReader::CreateSubDecoder(const nsACString& aType, MediaSourceDecoder*
return decoder.forget();
}
namespace {
class ChangeToHaveMetadata : public nsRunnable {
public:
ChangeToHaveMetadata(AbstractMediaDecoder* aDecoder) :
mDecoder(aDecoder)
{
}
NS_IMETHOD Run() MOZ_OVERRIDE MOZ_FINAL {
auto owner = mDecoder->GetOwner();
if (owner) {
owner->UpdateReadyStateForData(MediaDecoderOwner::NEXT_FRAME_WAIT_FOR_MSE_DATA);
}
return NS_OK;
}
private:
nsRefPtr<AbstractMediaDecoder> mDecoder;
};
}
nsresult
MediaSourceReader::Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime,
int64_t aCurrentTime)
{
ResetDecode();
if (!mMediaSource->ActiveSourceBuffers()->AllContainsTime (aTime / USECS_PER_S)) {
NS_DispatchToMainThread(new ChangeToHaveMetadata(mDecoder));
}
dom::SourceBufferList* sbl = mMediaSource->ActiveSourceBuffers();
if (sbl->AllContainsTime (aTime / USECS_PER_S)) {
if (GetAudioReader()) {
nsresult rv = GetAudioReader()->Seek(aTime, aStartTime, aEndTime, aCurrentTime);
if (NS_FAILED(rv)) {
return rv;
}
// Loop until we have the requested time range in the source buffers.
// This is a workaround for our lack of async functionality in the
// MediaDecoderStateMachine. Bug 979104 implements what we need and
// we'll remove this for an async approach based on that in bug XXXXXXX.
while (!mMediaSource->ActiveSourceBuffers()->AllContainsTime (aTime / USECS_PER_S)
&& !IsShutdown()) {
mMediaSource->WaitForData();
MaybeSwitchVideoReaders(aTime);
}
if (IsShutdown()) {
return NS_OK;
}
ResetDecode();
if (GetAudioReader()) {
nsresult rv = GetAudioReader()->Seek(aTime, aStartTime, aEndTime, aCurrentTime);
if (NS_FAILED(rv)) {
return rv;
}
if (GetVideoReader()) {
nsresult rv = GetVideoReader()->Seek(aTime, aStartTime, aEndTime, aCurrentTime);
if (NS_FAILED(rv)) {
return rv;
}
}
if (GetVideoReader()) {
nsresult rv = GetVideoReader()->Seek(aTime, aStartTime, aEndTime, aCurrentTime);
if (NS_FAILED(rv)) {
return rv;
}
}
return NS_OK;

View File

@ -493,6 +493,8 @@ SourceBuffer::AppendData(const uint8_t* aData, uint32_t aLength, ErrorResult& aR
// Schedule the state machine thread to ensure playback starts
// if required when data is appended.
mMediaSource->GetDecoder()->ScheduleStateMachineThread();
mMediaSource->NotifyGotData();
}
void

View File

@ -14,6 +14,11 @@ WebMWriter::WebMWriter(uint32_t aTrackTypes) : ContainerWriter()
mEbmlComposer = new EbmlComposer();
}
WebMWriter::~WebMWriter()
{
// Out-of-line dtor so mEbmlComposer nsAutoPtr can delete a complete type.
}
nsresult
WebMWriter::WriteEncodedTrack(const EncodedFrameContainer& aData,
uint32_t aFlags)

View File

@ -47,6 +47,8 @@ public:
// aTrackTypes indicate this muxer should multiplex into Video only or A/V foramt.
// Run in MediaRecorder thread
WebMWriter(uint32_t aTrackTypes);
virtual ~WebMWriter();
// WriteEncodedTrack inserts raw packets into WebM stream.
nsresult WriteEncodedTrack(const EncodedFrameContainer &aData,
uint32_t aFlags = 0) MOZ_OVERRIDE;

View File

@ -2166,8 +2166,12 @@ nsFocusManager::SetCaretVisible(nsIPresShell* aPresShell,
nsISelection* domSelection = docFrameSelection->
GetSelection(nsISelectionController::SELECTION_NORMAL);
if (domSelection) {
nsCOMPtr<nsISelectionController> selCon(do_QueryInterface(aPresShell));
if (!selCon) {
return NS_ERROR_FAILURE;
}
// First, hide the caret to prevent attempting to show it in SetCaretDOMSelection
caret->SetCaretVisible(false);
selCon->SetCaretEnabled(false);
// Caret must blink on non-editable elements
caret->SetIgnoreUserModify(true);
@ -2178,13 +2182,8 @@ nsFocusManager::SetCaretVisible(nsIPresShell* aPresShell,
// fields, which have a different frame selection from the document.
// They will take care of making the caret visible themselves.
nsCOMPtr<nsISelectionController> selCon(do_QueryInterface(aPresShell));
if (!selCon)
return NS_ERROR_FAILURE;
selCon->SetCaretReadOnly(false);
selCon->SetCaretEnabled(aVisible);
caret->SetCaretVisible(aVisible);
}
}

View File

@ -570,7 +570,7 @@ nsPIDOMWindow::nsPIDOMWindow(nsPIDOMWindow *aOuterWindow)
mRunningTimeout(nullptr), mMutationBits(0), mIsDocumentLoaded(false),
mIsHandlingResizeEvent(false), mIsInnerWindow(aOuterWindow != nullptr),
mMayHavePaintEventListener(false), mMayHaveTouchEventListener(false),
mMayHaveMouseEnterLeaveEventListener(false),
mMayHaveTouchCaret(false), mMayHaveMouseEnterLeaveEventListener(false),
mMayHavePointerEnterLeaveEventListener(false),
mIsModalContentWindow(false),
mIsActive(false), mIsBackground(false),

View File

@ -60,8 +60,8 @@ enum UIStateChangeType
};
#define NS_PIDOMWINDOW_IID \
{ 0xf26953de, 0xa799, 0x4a92, \
{ 0x87, 0x49, 0x7c, 0x37, 0xe5, 0x90, 0x3f, 0x37 } }
{ 0x33403513, 0x6e4a, 0x4985, \
{ 0x99, 0x8d, 0xfc, 0x02, 0x81, 0x6e, 0xb9, 0xf2 } }
class nsPIDOMWindow : public nsIDOMWindowInternal
{
@ -468,6 +468,21 @@ public:
return mMayHaveTouchEventListener;
}
/**
* Will be called when touch caret visibility has changed. mMayHaveTouchCaret
* is set if that some node (this window, its document, or content in that
* document) has a visible touch caret.
*/
void SetMayHaveTouchCaret(bool aSetValue)
{
mMayHaveTouchCaret = aSetValue;
}
bool MayHaveTouchCaret()
{
return mMayHaveTouchCaret;
}
/**
* Moves the top-level window into fullscreen mode if aIsFullScreen is true,
* otherwise exits fullscreen. If aRequireTrust is true, this method only
@ -761,6 +776,7 @@ protected:
bool mIsInnerWindow;
bool mMayHavePaintEventListener;
bool mMayHaveTouchEventListener;
bool mMayHaveTouchCaret;
bool mMayHaveMouseEnterLeaveEventListener;
bool mMayHavePointerEnterLeaveEventListener;

View File

@ -1405,7 +1405,7 @@ WrapNativeParent(JSContext* cx, T* p, nsWrapperCache* cache,
// If useXBLScope is true, it means that the canonical reflector for this
// native object should live in the XBL scope.
if (xpc::IsInXBLScope(parent)) {
if (xpc::IsInContentXBLScope(parent)) {
return parent;
}
JS::Rooted<JSObject*> rootedParent(cx, parent);

View File

@ -24,7 +24,7 @@ USING_BLUETOOTH_NAMESPACE
* BluetoothRequestParent::ReplyRunnable
******************************************************************************/
class BluetoothRequestParent::ReplyRunnable : public BluetoothReplyRunnable
class BluetoothRequestParent::ReplyRunnable MOZ_FINAL : public BluetoothReplyRunnable
{
BluetoothRequestParent* mRequest;
@ -59,8 +59,7 @@ public:
void
Revoke()
{
MOZ_ASSERT(NS_IsMainThread());
mRequest = nullptr;
ReleaseMembers();
}
virtual bool
@ -68,6 +67,14 @@ public:
{
MOZ_CRASH("This should never be called!");
}
virtual void
ReleaseMembers() MOZ_OVERRIDE
{
MOZ_ASSERT(NS_IsMainThread());
mRequest = nullptr;
BluetoothReplyRunnable::ReleaseMembers();
}
};
/*******************************************************************************

View File

@ -1,7 +1,6 @@
# nsDOMIdentity.js
component {210853d9-2c97-4669-9761-b1ab9cbf57ef} nsDOMIdentity.js
contract @mozilla.org/dom/identity;1 {210853d9-2c97-4669-9761-b1ab9cbf57ef}
category JavaScript-navigator-property mozId @mozilla.org/dom/identity;1
contract @mozilla.org/identity/manager;1 {210853d9-2c97-4669-9761-b1ab9cbf57ef}
# nsIDService.js (initialization on startup)
component {4e0a0e98-b1d3-4745-a1eb-f815199dd06b} nsIDService.js

View File

@ -48,29 +48,10 @@ const ERRORS = {
"The request() method may only be invoked when handling user input",
};
function nsDOMIdentity(aIdentityInternal) {
this._identityInternal = aIdentityInternal;
function nsDOMIdentity() {
}
nsDOMIdentity.prototype = {
__exposedProps__: {
// Relying Party (RP)
watch: 'r',
request: 'r',
logout: 'r',
get: 'r',
getVerifiedEmail: 'r',
// Provisioning
beginProvisioning: 'r',
genKeyPair: 'r',
registerCertificate: 'r',
raiseProvisioningFailure: 'r',
// Authentication
beginAuthentication: 'r',
completeAuthentication: 'r',
raiseAuthenticationFailure: 'r'
},
// require native events unless syntheticEventsOk is set
get nativeEventsRequired() {
@ -149,7 +130,7 @@ nsDOMIdentity.prototype = {
// broken client to be able to call watch() any more. It's broken.
return;
}
this._identityInternal._mm.sendAsyncMessage("Identity:RP:Watch", message);
this._mm.sendAsyncMessage("Identity:RP:Watch", message);
},
request: function nsDOMIdentity_request(aOptions = {}) {
@ -219,7 +200,7 @@ nsDOMIdentity.prototype = {
}
this._rpCalls++;
this._identityInternal._mm.sendAsyncMessage("Identity:RP:Request", message);
this._mm.sendAsyncMessage("Identity:RP:Request", message);
},
logout: function nsDOMIdentity_logout() {
@ -239,7 +220,7 @@ nsDOMIdentity.prototype = {
return;
}
this._identityInternal._mm.sendAsyncMessage("Identity:RP:Logout", message);
this._mm.sendAsyncMessage("Identity:RP:Logout", message);
},
/*
@ -322,7 +303,7 @@ nsDOMIdentity.prototype = {
}
this._beginProvisioningCallback = aCallback;
this._identityInternal._mm.sendAsyncMessage("Identity:IDP:BeginProvisioning",
this._mm.sendAsyncMessage("Identity:IDP:BeginProvisioning",
this.DOMIdentityMessage());
},
@ -339,7 +320,7 @@ nsDOMIdentity.prototype = {
}
this._genKeyPairCallback = aCallback;
this._identityInternal._mm.sendAsyncMessage("Identity:IDP:GenKeyPair",
this._mm.sendAsyncMessage("Identity:IDP:GenKeyPair",
this.DOMIdentityMessage());
},
@ -355,7 +336,7 @@ nsDOMIdentity.prototype = {
let message = this.DOMIdentityMessage();
message.cert = aCertificate;
this._identityInternal._mm.sendAsyncMessage("Identity:IDP:RegisterCertificate", message);
this._mm.sendAsyncMessage("Identity:IDP:RegisterCertificate", message);
},
raiseProvisioningFailure: function nsDOMIdentity_raiseProvisioningFailure(aReason) {
@ -370,7 +351,7 @@ nsDOMIdentity.prototype = {
let message = this.DOMIdentityMessage();
message.reason = aReason;
this._identityInternal._mm.sendAsyncMessage("Identity:IDP:ProvisioningFailure", message);
this._mm.sendAsyncMessage("Identity:IDP:ProvisioningFailure", message);
},
/**
@ -390,7 +371,7 @@ nsDOMIdentity.prototype = {
}
this._beginAuthenticationCallback = aCallback;
this._identityInternal._mm.sendAsyncMessage("Identity:IDP:BeginAuthentication",
this._mm.sendAsyncMessage("Identity:IDP:BeginAuthentication",
this.DOMIdentityMessage());
},
@ -403,7 +384,7 @@ nsDOMIdentity.prototype = {
}
this._authenticationEnded = true;
this._identityInternal._mm.sendAsyncMessage("Identity:IDP:CompleteAuthentication",
this._mm.sendAsyncMessage("Identity:IDP:CompleteAuthentication",
this.DOMIdentityMessage());
},
@ -417,27 +398,7 @@ nsDOMIdentity.prototype = {
let message = this.DOMIdentityMessage();
message.reason = aReason;
this._identityInternal._mm.sendAsyncMessage("Identity:IDP:AuthenticationFailure", message);
},
// Private.
_init: function nsDOMIdentity__init(aWindow) {
this._initializeState();
// Store window and origin URI.
this._window = aWindow;
this._origin = aWindow.document.nodePrincipal.origin;
this._appStatus = aWindow.document.nodePrincipal.appStatus;
this._appId = aWindow.document.nodePrincipal.appId;
// Setup identifiers for current window.
let util = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
// We need to inherit the id from the internalIdentity service.
// See comments below in that service's init.
this._id = this._identityInternal._id;
this._mm.sendAsyncMessage("Identity:IDP:AuthenticationFailure", message);
},
/**
@ -457,12 +418,18 @@ nsDOMIdentity.prototype = {
this._beginAuthenticationCallback = null;
},
_receiveMessage: function nsDOMIdentity_receiveMessage(aMessage) {
// nsIMessageListener
receiveMessage: function nsDOMIdentity_receiveMessage(aMessage) {
let msg = aMessage.json;
// Is this message intended for this window?
if (msg.id != this._id) {
return;
}
switch (aMessage.name) {
case "Identity:ResetState":
if (!this._identityInternal._debug) {
if (!this._debug) {
return;
}
this._initializeState();
@ -538,10 +505,6 @@ nsDOMIdentity.prototype = {
}
},
_log: function nsDOMIdentity__log(msg) {
this._identityInternal._log(msg);
},
_callGenKeyPairCallback: function nsDOMIdentity__callGenKeyPairCallback(message) {
// create a pubkey object that works
let chrome_pubkey = JSON.parse(message.publicKey);
@ -642,32 +605,10 @@ nsDOMIdentity.prototype = {
return message;
},
uninit: function DOMIdentity_uninit() {
this._log("nsDOMIdentity uninit() " + this._id);
this._identityInternal._mm.sendAsyncMessage(
"Identity:RP:Unwatch",
{ id: this._id }
);
}
};
/**
* Internal functions that shouldn't be exposed to content.
*/
function nsDOMIdentityInternal() {
}
nsDOMIdentityInternal.prototype = {
// nsIMessageListener
receiveMessage: function nsDOMIdentityInternal_receiveMessage(aMessage) {
let msg = aMessage.json;
// Is this message intended for this window?
if (msg.id != this._id) {
return;
}
this._identity._receiveMessage(aMessage);
},
/*
* Internal methods that are not exposed to content.
* See dom/webidl/Identity.webidl for the public interface.
*/
// nsIObserver
observe: function nsDOMIdentityInternal_observe(aSubject, aTopic, aData) {
@ -676,11 +617,10 @@ nsDOMIdentityInternal.prototype = {
return;
}
this._identity.uninit();
this.uninit();
Services.obs.removeObserver(this, "inner-window-destroyed");
this._identity._initializeState();
this._identity = null;
this._initializeState();
// TODO: Also send message to DOMIdentity notifiying window is no longer valid
// ie. in the case that the user closes the auth. window and we need to know.
@ -696,7 +636,8 @@ nsDOMIdentityInternal.prototype = {
this._mm = null;
},
// nsIDOMGlobalPropertyInitializer
// Because we implement nsIDOMGlobalPropertyInitializer, our init() method
// is invoked with content window as its single argument.
init: function nsDOMIdentityInternal_init(aWindow) {
if (Services.prefs.getPrefType(PREF_ENABLED) != Ci.nsIPrefBranch.PREF_BOOL
|| !Services.prefs.getBoolPref(PREF_ENABLED)) {
@ -720,8 +661,17 @@ nsDOMIdentityInternal.prototype = {
// nsDOMIdentity needs to know our _id, so this goes after
// its creation.
this._identity = new nsDOMIdentity(this);
this._identity._init(aWindow);
this._initializeState();
// Store window and origin URI.
this._window = aWindow;
this._origin = aWindow.document.nodePrincipal.origin;
this._appStatus = aWindow.document.nodePrincipal.appStatus;
this._appId = aWindow.document.nodePrincipal.appId;
// Setup identifiers for current window.
let util = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
this._log("init was called from " + aWindow.document.location);
@ -745,8 +695,14 @@ nsDOMIdentityInternal.prototype = {
// Setup observers so we can remove message listeners.
Services.obs.addObserver(this, "inner-window-destroyed", false);
},
return this._identity;
uninit: function DOMIdentity_uninit() {
this._log("nsDOMIdentity uninit() " + this._id);
this._mm.sendAsyncMessage(
"Identity:RP:Unwatch",
{ id: this._id }
);
},
// Private.
@ -760,9 +716,11 @@ nsDOMIdentityInternal.prototype = {
// Component setup.
classID: Components.ID("{210853d9-2c97-4669-9761-b1ab9cbf57ef}"),
QueryInterface: XPCOMUtils.generateQI(
[Ci.nsIDOMGlobalPropertyInitializer, Ci.nsIMessageListener]
),
QueryInterface: XPCOMUtils.generateQI([
Ci.nsIMessageListener,
Ci.nsIObserver,
Ci.nsIDOMGlobalPropertyInitializer
]),
classInfo: XPCOMUtils.generateCI({
classID: Components.ID("{210853d9-2c97-4669-9761-b1ab9cbf57ef}"),
@ -804,4 +762,4 @@ function assertCorrectCallbacks(aOptions) {
}
}
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([nsDOMIdentityInternal]);
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([nsDOMIdentity]);

View File

@ -2009,7 +2009,8 @@ TabChild::RecvRealTouchEvent(const WidgetTouchEvent& aEvent,
nsCOMPtr<nsPIDOMWindow> outerWindow = do_GetInterface(WebNavigation());
nsCOMPtr<nsPIDOMWindow> innerWindow = outerWindow->GetCurrentInnerWindow();
if (!innerWindow || !innerWindow->HasTouchEventListeners()) {
if (!innerWindow || (!innerWindow->HasTouchEventListeners() &&
!innerWindow->MayHaveTouchCaret())) {
SendContentReceivedTouch(aGuid, false);
return true;
}

View File

@ -19,6 +19,7 @@ const PC_SESSION_CONTRACT = "@mozilla.org/dom/rtcsessiondescription;1";
const PC_MANAGER_CONTRACT = "@mozilla.org/dom/peerconnectionmanager;1";
const PC_STATS_CONTRACT = "@mozilla.org/dom/rtcstatsreport;1";
const PC_IDENTITY_CONTRACT = "@mozilla.org/dom/rtcidentityassertion;1";
const PC_STATIC_CONTRACT = "@mozilla.org/dom/peerconnectionstatic;1";
const PC_CID = Components.ID("{00e0e20d-1494-4776-8e0e-0f0acbea3c79}");
const PC_OBS_CID = Components.ID("{d1748d4c-7f6a-4dc5-add6-d55b7678537e}");
@ -27,12 +28,14 @@ const PC_SESSION_CID = Components.ID("{1775081b-b62d-4954-8ffe-a067bbf508a7}");
const PC_MANAGER_CID = Components.ID("{7293e901-2be3-4c02-b4bd-cbef6fc24f78}");
const PC_STATS_CID = Components.ID("{7fe6e18b-0da3-4056-bf3b-440ef3809e06}");
const PC_IDENTITY_CID = Components.ID("{1abc7499-3c54-43e0-bd60-686e2703f072}");
const PC_STATIC_CID = Components.ID("{0fb47c47-a205-4583-a9fc-cbadf8c95880}");
// Global list of PeerConnection objects, so they can be cleaned up when
// a page is torn down. (Maps inner window ID to an array of PC objects).
function GlobalPCList() {
this._list = {};
this._networkdown = false; // XXX Need to query current state somehow
this._lifecycleobservers = {};
Services.obs.addObserver(this, "inner-window-destroyed", true);
Services.obs.addObserver(this, "profile-change-net-teardown", true);
Services.obs.addObserver(this, "network:offline-about-to-go-offline", true);
@ -52,6 +55,12 @@ GlobalPCList.prototype = {
}
},
notifyLifecycleObservers: function(pc, type) {
for (var key of Object.keys(this._lifecycleobservers)) {
this._lifecycleobservers[key](pc, pc._winID, type);
}
},
addPC: function(pc) {
let winID = pc._winID;
if (this._list[winID]) {
@ -97,7 +106,12 @@ GlobalPCList.prototype = {
};
if (topic == "inner-window-destroyed") {
cleanupWinId(this._list, subject.QueryInterface(Ci.nsISupportsPRUint64).data);
let winID = subject.QueryInterface(Ci.nsISupportsPRUint64).data;
cleanupWinId(this._list, winID);
if (this._lifecycleobservers.hasOwnProperty(winID)) {
delete this._lifecycleobservers[winID];
}
} else if (topic == "profile-change-net-teardown" ||
topic == "network:offline-about-to-go-offline") {
// Delete all peerconnections on shutdown - mostly synchronously (we
@ -121,6 +135,9 @@ GlobalPCList.prototype = {
}
},
_registerPeerConnectionLifecycleCallback: function(winID, cb) {
this._lifecycleobservers[winID] = cb;
},
};
let _globalPCList = new GlobalPCList();
@ -335,6 +352,7 @@ RTCPeerConnection.prototype = {
this._impl.initialize(this._observer, this._win, rtcConfig,
Services.tm.currentThread);
this._initIdp();
_globalPCList.notifyLifecycleObservers(this, "initialized");
},
get _impl() {
@ -877,6 +895,7 @@ RTCPeerConnection.prototype = {
},
get peerIdentity() { return this._peerIdentity; },
get id() { return this._impl.id; },
get iceGatheringState() { return this._iceGatheringState; },
get iceConnectionState() { return this._iceConnectionState; },
@ -899,10 +918,12 @@ RTCPeerConnection.prototype = {
changeIceGatheringState: function(state) {
this._iceGatheringState = state;
_globalPCList.notifyLifecycleObservers(this, "icegatheringstatechange");
},
changeIceConnectionState: function(state) {
this._iceConnectionState = state;
_globalPCList.notifyLifecycleObservers(this, "iceconnectionstatechange");
this.dispatchEvent(new this._win.Event("iceconnectionstatechange"));
},
@ -1284,11 +1305,32 @@ PeerConnectionObserver.prototype = {
},
};
function RTCPeerConnectionStatic() {
}
RTCPeerConnectionStatic.prototype = {
classDescription: "mozRTCPeerConnectionStatic",
QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports,
Ci.nsIDOMGlobalPropertyInitializer]),
classID: PC_STATIC_CID,
contractID: PC_STATIC_CONTRACT,
init: function(win) {
this._winID = win.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils).currentInnerWindowID;
},
registerPeerConnectionLifecycleCallback: function(cb) {
_globalPCList._registerPeerConnectionLifecycleCallback(this._winID, cb);
},
};
this.NSGetFactory = XPCOMUtils.generateNSGetFactory(
[GlobalPCList,
RTCIceCandidate,
RTCSessionDescription,
RTCPeerConnection,
RTCPeerConnectionStatic,
RTCStatsReport,
RTCIdentityAssertion,
PeerConnectionObserver]

View File

@ -5,6 +5,7 @@ component {1775081b-b62d-4954-8ffe-a067bbf508a7} PeerConnection.js
component {7293e901-2be3-4c02-b4bd-cbef6fc24f78} PeerConnection.js
component {7fe6e18b-0da3-4056-bf3b-440ef3809e06} PeerConnection.js
component {1abc7499-3c54-43e0-bd60-686e2703f072} PeerConnection.js
component {0fb47c47-a205-4583-a9fc-cbadf8c95880} PeerConnection.js
contract @mozilla.org/dom/peerconnection;1 {00e0e20d-1494-4776-8e0e-0f0acbea3c79}
contract @mozilla.org/dom/peerconnectionobserver;1 {d1748d4c-7f6a-4dc5-add6-d55b7678537e}
@ -13,3 +14,4 @@ contract @mozilla.org/dom/rtcsessiondescription;1 {1775081b-b62d-4954-8ffe-a067b
contract @mozilla.org/dom/peerconnectionmanager;1 {7293e901-2be3-4c02-b4bd-cbef6fc24f78}
contract @mozilla.org/dom/rtcstatsreport;1 {7fe6e18b-0da3-4056-bf3b-440ef3809e06}
contract @mozilla.org/dom/rtcidentityassertion;1 {1abc7499-3c54-43e0-bd60-686e2703f072}
contract @mozilla.org/dom/peerconnectionstatic;1 {0fb47c47-a205-4583-a9fc-cbadf8c95880}

View File

@ -19,6 +19,8 @@ skip-if = os == 'mac' || toolkit=='gonk' # b2g(Bug 960442, video support for Web
skip-if = os == 'mac' || toolkit=='gonk' # b2g(Bug 960442, video support for WebRTC is disabled on b2g) b2g-debug(Bug 960442, video support for WebRTC is disabled on b2g)
[test_dataChannel_basicDataOnly.html]
[test_dataChannel_basicVideo.html]
skip-if = toolkit=='gonk' # b2g emulator seems to bee too slow (Bug 1016498 and 1008080)
[test_dataChannel_bug1013809.html]
skip-if = toolkit=='gonk' # b2g(Bug 960442, video support for WebRTC is disabled on b2g) b2g-debug(Bug 960442, video support for WebRTC is disabled on b2g)
[test_dataChannel_noOffer.html]
[test_getUserMedia_basicAudio.html]
@ -60,6 +62,8 @@ skip-if = toolkit=='gonk' # b2g(Bug 960442, video support for WebRTC is disabled
skip-if = toolkit=='gonk' # b2g(Bug 960442, video support for WebRTC is disabled on b2g) b2g-debug(Bug 960442, video support for WebRTC is disabled on b2g)
[test_peerConnection_bug834153.html]
[test_peerConnection_bug835370.html]
skip-if = toolkit=='gonk' # b2g emulator seems to bee too slow (Bug 1016498 and 1008080)
[test_peerConnection_bug1013809.html]
[test_peerConnection_close.html]
[test_peerConnection_errorCallbacks.html]
[test_peerConnection_offerRequiresReceiveAudio.html]

View File

@ -481,8 +481,6 @@ function PeerConnectionTest(options) {
else
this.pcRemote = null;
this.connected = false;
// Create command chain instance and assign default commands
this.chain = new CommandChain(this, options.commands);
if (!options.is_local) {
@ -510,7 +508,7 @@ function PeerConnectionTest(options) {
* Callback to execute when the peer connection has been closed successfully
*/
PeerConnectionTest.prototype.close = function PCT_close(onSuccess) {
info("Closing peer connections. Connection state=" + this.connected);
info("Closing peer connections");
var self = this;
var closeTimeout = null;
@ -533,7 +531,6 @@ PeerConnectionTest.prototype.close = function PCT_close(onSuccess) {
is(self.pcRemote.signalingState, "closed", "pcRemote is in 'closed' state");
}
clearTimeout(closeTimeout);
self.connected = false;
everythingClosed = true;
onSuccess();
}
@ -566,11 +563,14 @@ PeerConnectionTest.prototype.close = function PCT_close(onSuccess) {
self.waitingForRemote = true;
self.pcRemote.close();
}
verifyClosed();
// give the signals handlers time to fire
setTimeout(verifyClosed, 1000);
}
closeTimeout = setTimeout(function() {
ok(false, "Closing PeerConnections timed out!");
var closed = ((self.pcLocal && (self.pcLocal.signalingState === "closed")) &&
(self.pcRemote && (self.pcRemote.signalingState === "closed")));
ok(closed, "Closing PeerConnections timed out");
// it is not a success, but the show must go on
onSuccess();
}, 60000);
@ -794,53 +794,173 @@ DataChannelTest.prototype = Object.create(PeerConnectionTest.prototype, {
* Close the open data channels, followed by the underlying peer connection
*
* @param {Function} onSuccess
* Callback to execute when the connection has been closed
* Callback to execute when all connections have been closed
*/
value : function DCT_close(onSuccess) {
var self = this;
var pendingDcClose = []
var closeTimeout = null;
function _closeChannels() {
var length = self.pcLocal.dataChannels.length;
info("DataChannelTest.close() called");
if (length > 0) {
self.closeDataChannel(length - 1, function () {
_closeChannels();
});
function _closePeerConnection() {
info("DataChannelTest closing PeerConnection");
PeerConnectionTest.prototype.close.call(self, onSuccess);
}
function _closePeerConnectionCallback(index) {
info("_closePeerConnection called with index " + index);
var pos = pendingDcClose.indexOf(index);
if (pos != -1) {
pendingDcClose.splice(pos, 1);
}
else {
PeerConnectionTest.prototype.close.call(self, onSuccess);
info("_closePeerConnection index " + index + " is missing from pendingDcClose: " + pendingDcClose);
}
if (pendingDcClose.length === 0) {
clearTimeout(closeTimeout);
_closePeerConnection();
}
}
_closeChannels();
var myDataChannels = null;
if (self.pcLocal) {
myDataChannels = self.pcLocal.dataChannels;
}
else if (self.pcRemote) {
myDataChannels = self.pcRemote.dataChannels;
}
var length = myDataChannels.length;
for (var i = 0; i < length; i++) {
var dataChannel = myDataChannels[i];
if (dataChannel.readyState !== "closed") {
pendingDcClose.push(i);
self.closeDataChannels(i, _closePeerConnectionCallback);
}
}
if (pendingDcClose.length === 0) {
_closePeerConnection();
}
else {
closeTimeout = setTimeout(function() {
ok(false, "Failed to properly close data channels: " +
pendingDcClose);
_closePeerConnection();
}, 60000);
}
}
},
closeDataChannel : {
closeDataChannels : {
/**
* Close the specified data channel
* Close the specified data channels
*
* @param {Number} index
* Index of the data channel to close on both sides
* Index of the data channels to close on both sides
* @param {Function} onSuccess
* Callback to execute when the data channel has been closed
* Callback to execute when the data channels has been closed
*/
value : function DCT_closeDataChannel(index, onSuccess) {
var localChannel = this.pcLocal.dataChannels[index];
var remoteChannel = this.pcRemote.dataChannels[index];
value : function DCT_closeDataChannels(index, onSuccess) {
info("_closeDataChannels called with index: " + index);
var localChannel = null;
if (this.pcLocal) {
localChannel = this.pcLocal.dataChannels[index];
}
var remoteChannel = null;
if (this.pcRemote) {
remoteChannel = this.pcRemote.dataChannels[index];
}
var self = this;
var wait = false;
var pollingMode = false;
var everythingClosed = false;
var verifyInterval = null;
var remoteCloseTimer = null;
// Register handler for remote channel, cause we have to wait until
// the current close operation has been finished.
remoteChannel.onclose = function () {
self.pcRemote.dataChannels.splice(index, 1);
function _allChannelsAreClosed() {
var ret = null;
if (localChannel) {
ret = (localChannel.readyState === "closed");
}
if (remoteChannel) {
if (ret !== null) {
ret = (ret && (remoteChannel.readyState === "closed"));
}
else {
ret = (remoteChannel.readyState === "closed");
}
}
return ret;
}
onSuccess(remoteChannel);
};
function verifyClosedChannels() {
if (everythingClosed) {
// safety protection against events firing late
return;
}
if (_allChannelsAreClosed) {
ok(true, "DataChannel(s) have reached 'closed' state for data channel " + index);
if (remoteCloseTimer !== null) {
clearTimeout(remoteCloseTimer);
}
if (verifyInterval !== null) {
clearInterval(verifyInterval);
}
everythingClosed = true;
onSuccess(index);
}
else {
info("Still waiting for DataChannel closure");
}
}
localChannel.close();
this.pcLocal.dataChannels.splice(index, 1);
if ((localChannel) && (localChannel.readyState !== "closed")) {
// in case of steeplechase there is no far end, so we can only poll
if (remoteChannel) {
remoteChannel.onclose = function () {
is(remoteChannel.readyState, "closed", "remoteChannel is in state 'closed'");
verifyClosedChannels();
};
}
else {
pollingMode = true;
verifyInterval = setInterval(verifyClosedChannels, 1000);
}
localChannel.close();
wait = true;
}
if ((remoteChannel) && (remoteChannel.readyState !== "closed")) {
if (localChannel) {
localChannel.onclose = function () {
is(localChannel.readyState, "closed", "localChannel is in state 'closed'");
verifyClosedChannels();
};
// Apparently we are running a local test which has both ends of the
// data channel locally available, so by default lets wait for the
// remoteChannel.onclose handler from above to confirm closure on both
// ends.
remoteCloseTimer = setTimeout(function() {
todo(false, "localChannel.close() did not resulted in close signal on remote side");
remoteChannel.close();
verifyClosedChannels();
}, 30000);
}
else {
pollingMode = true;
verifyTimer = setInterval(verifyClosedChannels, 1000);
remoteChannel.close();
}
wait = true;
}
if (!wait) {
onSuccess(index);
}
}
},
@ -860,7 +980,7 @@ DataChannelTest.prototype = Object.create(PeerConnectionTest.prototype, {
// Method to synchronize all asynchronous events.
function check_next_test() {
if (self.connected && localChannel && remoteChannel) {
if (localChannel && remoteChannel) {
onSuccess(localChannel, remoteChannel);
}
}
@ -925,8 +1045,7 @@ DataChannelTest.prototype = Object.create(PeerConnectionTest.prototype, {
setLocalDescription : {
/**
* Sets the local description for the specified peer connection instance
* and automatically handles the failure case. In case for the final call
* it will setup the requested datachannel.
* and automatically handles the failure case.
*
* @param {PeerConnectionWrapper} peer
The peer connection wrapper to run the command on
@ -936,70 +1055,52 @@ DataChannelTest.prototype = Object.create(PeerConnectionTest.prototype, {
* Callback to execute if the local description was set successfully
*/
value : function DCT_setLocalDescription(peer, desc, state, onSuccess) {
// If the peer has a remote offer we are in the final call, and have
// to wait for the datachannel connection to be open. It will also set
// the local description internally.
if (peer.signalingState === 'have-remote-offer') {
this.waitForInitialDataChannel(peer, desc, state, onSuccess);
}
else {
PeerConnectionTest.prototype.setLocalDescription.call(this, peer,
PeerConnectionTest.prototype.setLocalDescription.call(this, peer,
desc, state, onSuccess);
}
}
},
waitForInitialDataChannel : {
/**
* Create an initial data channel before the peer connection has been connected
* Wait for the initial data channel to get into the open state
*
* @param {PeerConnectionWrapper} peer
The peer connection wrapper to run the command on
* @param {mozRTCSessionDescription} desc
* Session description for the local description request
* The peer connection wrapper to run the command on
* @param {Function} onSuccess
* Callback when the creation was successful
*/
value : function DCT_waitForInitialDataChannel(peer, desc, state, onSuccess) {
var self = this;
value : function DCT_waitForInitialDataChannel(peer, onSuccess, onFailure) {
var dcConnectionTimeout = null;
var targetPeer = peer;
var targetChannel = null;
var sourcePeer = (peer == this.pcLocal) ? this.pcRemote : this.pcLocal;
var sourceChannel = null;
// Method to synchronize all asynchronous events which current happen
// due to a non-predictable flow. With bug 875346 fixed we will be able
// to simplify this code.
function check_next_test() {
if (self.connected && sourceChannel && targetChannel) {
onSuccess(sourceChannel, targetChannel);
}
function dataChannelConnected(channel) {
clearTimeout(dcConnectionTimeout);
is(channel.readyState, "open", peer + " dataChannels[0] is in state: 'open'");
onSuccess();
}
// Register 'onopen' handler for the first local data channel
sourcePeer.dataChannels[0].onopen = function (channel) {
sourceChannel = channel;
check_next_test();
};
if ((peer.dataChannels.length >= 1) &&
(peer.dataChannels[0].readyState === "open")) {
is(peer.dataChannels[0].readyState, "open", peer + " dataChannels[0] is in state: 'open'");
onSuccess();
return;
}
// Register handlers for the target peer
targetPeer.registerDataChannelOpenEvents(function (channel) {
targetChannel = channel;
check_next_test();
});
// TODO: drno: convert dataChannels into an object and make
// registerDataChannelOPenEvent a generic function
if (peer == this.pcLocal) {
peer.dataChannels[0].onopen = dataChannelConnected;
} else {
peer.registerDataChannelOpenEvents(dataChannelConnected);
}
PeerConnectionTest.prototype.setLocalDescription.call(this, targetPeer, desc,
state,
function () {
self.connected = true;
check_next_test();
}
);
dcConnectionTimeout = setTimeout(function () {
info(peer + " timed out while waiting for dataChannels[0] to connect");
onFailure();
}, 60000);
}
}
});
/**
@ -1966,10 +2067,7 @@ PeerConnectionWrapper.prototype = {
info(this + ": Register callbacks for 'ondatachannel' and 'onopen'");
this.ondatachannel = function (targetChannel) {
targetChannel.onopen = function (targetChannel) {
onDataChannelOpened(targetChannel);
};
targetChannel.onopen = onDataChannelOpened;
this.dataChannels.push(targetChannel);
};
},

View File

@ -134,6 +134,16 @@ var commandsPeerConnection = [
});
}
],
[
'PC_REMOTE_SET_LOCAL_DESCRIPTION',
function (test) {
test.setLocalDescription(test.pcRemote, test.pcRemote._last_answer, STABLE, function () {
is(test.pcRemote.signalingState, STABLE,
"signalingState after remote setLocalDescription is 'stable'");
test.next();
});
}
],
[
'PC_LOCAL_GET_ANSWER',
function (test) {
@ -161,16 +171,6 @@ var commandsPeerConnection = [
});
}
],
[
'PC_REMOTE_SET_LOCAL_DESCRIPTION',
function (test) {
test.setLocalDescription(test.pcRemote, test.pcRemote._last_answer, STABLE, function () {
is(test.pcRemote.signalingState, STABLE,
"signalingState after remote setLocalDescription is 'stable'");
test.next();
});
}
],
[
'PC_LOCAL_WAIT_FOR_ICE_CONNECTED',
function (test) {
@ -374,6 +374,42 @@ var commandsDataChannel = [
});
}
],
[
'PC_LOCAL_SETUP_DATA_CHANNEL_CALLBACK',
function (test) {
test.waitForInitialDataChannel(test.pcLocal, function () {
ok(true, test.pcLocal + " dataChannels[0] switched to 'open'");
}, function () {
ok(false, test.pcLocal + " initial dataChannels[0] failed to switch to 'open'");
unexpectedEventAndFinish(this, 'timeout')
});
test.next();
}
],
[
'PC_REMOTE_SETUP_DATA_CHANNEL_CALLBACK',
function (test) {
test.waitForInitialDataChannel(test.pcRemote, function () {
ok(true, test.pcRemote + " dataChannels[0] switched to 'open'");
}, function () {
ok(false, test.pcRemote + " initial dataChannels[0] failed to switch to 'open'");
unexpectedEventAndFinish(this, 'timeout');
});
test.next();
}
],
[
'PC_REMOTE_SET_LOCAL_DESCRIPTION',
function (test) {
test.setLocalDescription(test.pcRemote, test.pcRemote._last_answer, STABLE,
function () {
is(test.pcRemote.signalingState, STABLE,
"signalingState after remote setLocalDescription is 'stable'");
test.next();
}
);
}
],
[
'PC_LOCAL_SET_REMOTE_DESCRIPTION',
function (test) {
@ -386,18 +422,25 @@ var commandsDataChannel = [
}
],
[
'PC_REMOTE_SET_LOCAL_DESCRIPTION',
'PC_LOCAL_VERIFY_DATA_CHANNEL_STATE',
function (test) {
test.setLocalDescription(test.pcRemote, test.pcRemote._last_answer, STABLE,
function (sourceChannel, targetChannel) {
is(sourceChannel.readyState, "open", test.pcLocal + " is in state: 'open'");
is(targetChannel.readyState, "open", test.pcRemote + " is in state: 'open'");
is(test.pcRemote.signalingState, STABLE,
"signalingState after remote setLocalDescription is 'stable'");
test.next();
}
);
test.waitForInitialDataChannel(test.pcLocal, function() {
test.next();
}, function() {
ok(false, test.pcLocal + " initial dataChannels[0] failed to switch to 'open'");
unexpectedEventAndFinish(this, 'timeout')
});
}
],
[
'PC_REMOTE_VERIFY_DATA_CHANNEL_STATE',
function (test) {
test.waitForInitialDataChannel(test.pcRemote, function() {
test.next();
}, function() {
ok(false, test.pcRemote + " initial dataChannels[0] failed to switch to 'open'");
unexpectedEventAndFinish(this, 'timeout');
});
}
],
[
@ -507,11 +550,28 @@ var commandsDataChannel = [
}, options);
}
],
[
'SEND_MESSAGE_BACK_THROUGH_FIRST_CHANNEL',
function (test) {
var message = "Return a message also through 1st channel";
var options = {
sourceChannel: test.pcRemote.dataChannels[0],
targetChannel: test.pcLocal.dataChannels[0]
};
test.send(message, function (channel, data) {
is(test.pcLocal.dataChannels.indexOf(channel), 0, "1st channel used");
is(data, message, "Return message has the correct content.");
test.next();
}, options);
}
],
[
'CREATE_NEGOTIATED_DATA_CHANNEL',
function (test) {
var options = {negotiated:true, id: 5, protocol:"foo/bar", ordered:false,
maxRetransmits:500};
maxRetransmits:500};
test.createDataChannel(options, function (sourceChannel2, targetChannel2) {
is(sourceChannel2.readyState, "open", sourceChannel2 + " is in state: 'open'");
is(targetChannel2.readyState, "open", targetChannel2 + " is in state: 'open'");
@ -521,10 +581,11 @@ var commandsDataChannel = [
if (options.id != undefined) {
is(sourceChannel2.id, options.id, sourceChannel2 + " id is:" + sourceChannel2.id);
} else {
options.id = sourceChannel2.id;
}
var reliable = !options.ordered ? false : (options.maxRetransmits || options.maxRetransmitTime);
}
else {
options.id = sourceChannel2.id;
}
var reliable = !options.ordered ? false : (options.maxRetransmits || options.maxRetransmitTime);
is(sourceChannel2.protocol, options.protocol, sourceChannel2 + " protocol is:" + sourceChannel2.protocol);
is(sourceChannel2.reliable, reliable, sourceChannel2 + " reliable is:" + sourceChannel2.reliable);
/*
@ -562,30 +623,6 @@ var commandsDataChannel = [
is(channels.indexOf(channel), channels.length - 1, "Last channel used");
is(data, message, "Received message has the correct content.");
test.next();
});
}
],
[
'CLOSE_LAST_OPENED_DATA_CHANNEL2',
function (test) {
var channels = test.pcRemote.dataChannels;
test.closeDataChannel(channels.length - 1, function (channel) {
is(channel.readyState, "closed", "Channel is in state: 'closed'");
test.next();
});
}
],
[
'CLOSE_LAST_OPENED_DATA_CHANNEL',
function (test) {
var channels = test.pcRemote.dataChannels;
test.closeDataChannel(channels.length - 1, function (channel) {
is(channel.readyState, "closed", "Channel is in state: 'closed'");
test.next();
});
}

View File

@ -0,0 +1,31 @@
<!DOCTYPE HTML>
<html>
<head>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="head.js"></script>
<script type="application/javascript" src="pc.js"></script>
<script type="application/javascript" src="templates.js"></script>
<script type="application/javascript" src="turnConfig.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript">
createHTML({
bug: "796895",
title: "Basic data channel audio connection"
});
var test;
runTest(function () {
test = new DataChannelTest();
var sld = test.chain.remove("PC_REMOTE_SET_LOCAL_DESCRIPTION");
test.chain.insertAfter("PC_LOCAL_SET_REMOTE_DESCRIPTION", sld);
test.setMediaConstraints([{audio: true}], [{audio: true}]);
test.run();
}, true);
</script>
</pre>
</body>
</html>

View File

@ -0,0 +1,30 @@
<!DOCTYPE HTML>
<html>
<head>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="head.js"></script>
<script type="application/javascript" src="pc.js"></script>
<script type="application/javascript" src="templates.js"></script>
<script type="application/javascript" src="turnConfig.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript">
createHTML({
bug: "1013809",
title: "Audio-only peer connection with swapped setLocal and setRemote steps"
});
var test;
runTest(function (options) {
test = new PeerConnectionTest(options);
var sld = test.chain.remove("PC_REMOTE_SET_LOCAL_DESCRIPTION");
test.chain.insertAfter("PC_LOCAL_SET_REMOTE_DESCRIPTION", sld);
test.setMediaConstraints([{audio: true}], [{audio: true}]);
test.run();
});
</script>
</pre>
</body>
</html>

View File

@ -0,0 +1,70 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/.
*/
callback IdentityOnReadyCallback = void();
callback IdentityOnLoginCallback = void(DOMString identityAssertion);
callback IdentityOnLogoutCallback = void();
callback IdentityOnCancelCallback = void(DOMString? error);
callback IdentityOnErrorCallback = void(DOMString error);
dictionary IdentityWatchOptions {
// Required callback
IdentityOnLoginCallback onlogin;
// Optional parameters
DOMString wantIssuer;
DOMString loggedInUser;
// Optional callbacks
IdentityOnReadyCallback onready;
IdentityOnLogoutCallback onlogout;
IdentityOnErrorCallback onerror;
// Certified apps can specify this
DOMString audience;
};
dictionary IdentityRequestOptions {
// Optional parameters
long refreshAuthentication;
DOMString termsOfService;
DOMString privacyPolicy;
DOMString backgroundColor;
DOMString siteLogo;
DOMString siteName;
DOMString returnTo;
IdentityOnCancelCallback oncancel;
// Certified apps can specify this
DOMString origin;
};
dictionary IdentityGetOptions {
DOMString privacyPolicy;
DOMString termsOfService;
DOMString privacyURL;
DOMString tosURL;
DOMString siteName;
DOMString siteLogo;
};
[JSImplementation="@mozilla.org/identity/manager;1",
NoInterfaceObject,
NavigatorProperty="mozId",
Pref="dom.identity.enabled"]
interface IdentityManager {
void watch(optional IdentityWatchOptions options);
void request(optional IdentityRequestOptions options);
void logout();
[Pref="dom.identity.exposeLegacyGetAPI"]
void get(IdentityOnLoginCallback callback, optional IdentityGetOptions options);
[Pref="dom.identity.exposeLegacyGetVerifiedEmailAPI"]
void getVerifiedEmail(IdentityOnLoginCallback callback);
};

View File

@ -70,6 +70,7 @@ interface PeerConnectionImpl {
readonly attribute PCImplIceGatheringState iceGatheringState;
readonly attribute PCImplSignalingState signalingState;
readonly attribute PCImplSipccState sipccState;
readonly attribute DOMString id;
attribute DOMString peerIdentity;
readonly attribute boolean privacyRequested;

View File

@ -118,6 +118,9 @@ interface mozRTCPeerConnection : EventTarget {
[Pref="media.peerconnection.identity.enabled"]
readonly attribute RTCIdentityAssertion? peerIdentity;
[ChromeOnly]
readonly attribute DOMString id;
sequence<MediaStream> getLocalStreams ();
sequence<MediaStream> getRemoteStreams ();
MediaStream? getStreamById (DOMString streamId);
@ -148,3 +151,4 @@ interface mozRTCPeerConnection : EventTarget {
[Pref="media.peerconnection.identity.enabled"]
attribute EventHandler onidpvalidationerror;
};

View File

@ -0,0 +1,39 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/.
*/
/*
Right now, it is not possible to add static functions to a JS implemented
interface (see bug 863952), so we need to create a simple interface with a
trivial constructor and no data to hold these functions that really ought to
be static in mozRTCPeerConnection.
TODO(bcampen@mozilla.com) Merge this code into RTCPeerConnection once this
limitation is gone. (Bug 1017082)
*/
enum RTCLifecycleEvent {
"initialized",
"icegatheringstatechange",
"iceconnectionstatechange"
};
callback PeerConnectionLifecycleCallback = void (mozRTCPeerConnection pc,
unsigned long long windowId,
RTCLifecycleEvent eventType);
[ChromeOnly,
Pref="media.peerconnection.enabled",
JSImplementation="@mozilla.org/dom/peerconnectionstatic;1",
Constructor()]
interface mozRTCPeerConnectionStatic {
/* One slot per window (the window in which the register call is made),
automatically unregistered when window goes away.
Fires when a PC is created, and whenever the ICE connection state or
gathering state changes. */
void registerPeerConnectionLifecycleCallback(
PeerConnectionLifecycleCallback cb);
};

View File

@ -15,7 +15,8 @@ callback WebrtcGlobalLoggingCallback = void (sequence<DOMString> logMessages);
interface WebrtcGlobalInformation {
[Throws]
static void getAllStats(WebrtcGlobalStatisticsCallback callback);
static void getAllStats(WebrtcGlobalStatisticsCallback callback,
optional DOMString pcIdFilter);
[Throws]
static void getLogging(DOMString pattern,

View File

@ -212,6 +212,7 @@ WEBIDL_FILES = [
'IDBRequest.webidl',
'IDBTransaction.webidl',
'IDBVersionChangeEvent.webidl',
'Identity.webidl',
'ImageData.webidl',
'ImageDocument.webidl',
'InputEvent.webidl',
@ -298,6 +299,7 @@ WEBIDL_FILES = [
'RTCIceCandidate.webidl',
'RTCIdentityAssertion.webidl',
'RTCPeerConnection.webidl',
'RTCPeerConnectionStatic.webidl',
'RTCSessionDescription.webidl',
'RTCStatsReport.webidl',
'Screen.webidl',

View File

@ -104,7 +104,7 @@ static const JSClass gPrototypeJSClass = {
// Constructors/Destructors
nsXBLBinding::nsXBLBinding(nsXBLPrototypeBinding* aBinding)
: mMarkedForDeath(false)
, mUsingXBLScope(false)
, mUsingContentXBLScope(false)
, mPrototypeBinding(aBinding)
{
NS_ASSERTION(mPrototypeBinding, "Must have a prototype binding!");
@ -115,7 +115,7 @@ nsXBLBinding::nsXBLBinding(nsXBLPrototypeBinding* aBinding)
// Constructor used by web components.
nsXBLBinding::nsXBLBinding(ShadowRoot* aShadowRoot, nsXBLPrototypeBinding* aBinding)
: mMarkedForDeath(false),
mUsingXBLScope(false),
mUsingContentXBLScope(false),
mPrototypeBinding(aBinding),
mContent(aShadowRoot)
{
@ -278,7 +278,7 @@ nsXBLBinding::SetBoundElement(nsIContent* aElement)
// is not given in the handler declaration.
nsCOMPtr<nsIGlobalObject> go = mBoundElement->OwnerDoc()->GetScopeObject();
NS_ENSURE_TRUE_VOID(go && go->GetGlobalJSObject());
mUsingXBLScope = xpc::UseXBLScope(js::GetObjectCompartment(go->GetGlobalJSObject()));
mUsingContentXBLScope = xpc::UseContentXBLScope(js::GetObjectCompartment(go->GetGlobalJSObject()));
}
bool
@ -512,7 +512,7 @@ nsXBLBinding::InstallEventHandlers()
bool hasAllowUntrustedAttr = curr->HasAllowUntrustedAttr();
if ((hasAllowUntrustedAttr && curr->AllowUntrustedEvents()) ||
(!hasAllowUntrustedAttr && !isChromeDoc && !mUsingXBLScope)) {
(!hasAllowUntrustedAttr && !isChromeDoc && !mUsingContentXBLScope)) {
flags.mAllowUntrustedEvents = true;
}
@ -528,7 +528,7 @@ nsXBLBinding::InstallEventHandlers()
for (i = 0; i < keyHandlers->Count(); ++i) {
nsXBLKeyEventHandler* handler = keyHandlers->ObjectAt(i);
handler->SetIsBoundToChrome(isChromeDoc);
handler->SetUsingXBLScope(mUsingXBLScope);
handler->SetUsingContentXBLScope(mUsingContentXBLScope);
nsAutoString type;
handler->GetEventName(type);
@ -920,8 +920,8 @@ GetOrCreateMapEntryForPrototype(JSContext *cx, JS::Handle<JSObject*> proto)
// So we define two maps - one class objects that live in content (prototyped
// to content prototypes), and the other for class objects that live in the
// XBL scope (prototyped to cross-compartment-wrapped content prototypes).
const char* name = xpc::IsInXBLScope(proto) ? "__ContentClassObjectMap__"
: "__XBLClassObjectMap__";
const char* name = xpc::IsInContentXBLScope(proto) ? "__ContentClassObjectMap__"
: "__XBLClassObjectMap__";
// Now, enter the XBL scope, since that's where we need to operate, and wrap
// the proto accordingly.
@ -1116,7 +1116,7 @@ nsXBLBinding::LookupMember(JSContext* aCx, JS::Handle<jsid> aId,
// We do a release-mode assertion here to be extra safe.
JS::Rooted<JSObject*> boundScope(aCx,
js::GetGlobalForObjectCrossCompartment(mBoundElement->GetWrapper()));
MOZ_RELEASE_ASSERT(!xpc::IsInXBLScope(boundScope));
MOZ_RELEASE_ASSERT(!xpc::IsInContentXBLScope(boundScope));
JS::Rooted<JSObject*> xblScope(aCx, xpc::GetXBLScope(aCx, boundScope));
NS_ENSURE_TRUE(xblScope, false);
MOZ_ASSERT(boundScope != xblScope);

View File

@ -160,7 +160,7 @@ public:
protected:
bool mMarkedForDeath;
bool mUsingXBLScope;
bool mUsingContentXBLScope;
nsXBLPrototypeBinding* mPrototypeBinding; // Weak, but we're holding a ref to the docinfo
nsCOMPtr<nsIContent> mContent; // Strong. Our anonymous content stays around with us.

View File

@ -71,7 +71,7 @@ nsXBLKeyEventHandler::nsXBLKeyEventHandler(nsIAtom* aEventType, uint8_t aPhase,
mPhase(aPhase),
mType(aType),
mIsBoundToChrome(false),
mUsingXBLScope(false)
mUsingContentXBLScope(false)
{
}
@ -97,7 +97,7 @@ nsXBLKeyEventHandler::ExecuteMatchedHandlers(nsIDOMKeyEvent* aKeyEvent,
bool hasAllowUntrustedAttr = handler->HasAllowUntrustedAttr();
if ((trustedEvent ||
(hasAllowUntrustedAttr && handler->AllowUntrustedEvents()) ||
(!hasAllowUntrustedAttr && !mIsBoundToChrome && !mUsingXBLScope)) &&
(!hasAllowUntrustedAttr && !mIsBoundToChrome && !mUsingContentXBLScope)) &&
handler->KeyEventMatched(aKeyEvent, aCharCode, aIgnoreShiftKey)) {
handler->ExecuteHandler(target, aKeyEvent);
executed = true;

View File

@ -86,9 +86,9 @@ public:
mIsBoundToChrome = aIsBoundToChrome;
}
void SetUsingXBLScope(bool aUsingXBLScope)
void SetUsingContentXBLScope(bool aUsingContentXBLScope)
{
mUsingXBLScope = aUsingXBLScope;
mUsingContentXBLScope = aUsingContentXBLScope;
}
private:
@ -101,7 +101,7 @@ private:
uint8_t mPhase;
uint8_t mType;
bool mIsBoundToChrome;
bool mUsingXBLScope;
bool mUsingContentXBLScope;
};
nsresult

View File

@ -104,7 +104,7 @@ nsXBLProtoImplMethod::InstallMember(JSContext* aCx,
MOZ_ASSERT(js::IsObjectInContextCompartment(aTargetClassObject, aCx));
JS::Rooted<JSObject*> globalObject(aCx, JS_GetGlobalForObject(aCx, aTargetClassObject));
MOZ_ASSERT(xpc::IsInXBLScope(globalObject) ||
MOZ_ASSERT(xpc::IsInContentXBLScope(globalObject) ||
globalObject == xpc::GetXBLScope(aCx, globalObject));
JS::Rooted<JSObject*> jsMethodObject(aCx, GetCompiledMethod());

View File

@ -129,7 +129,7 @@ nsXBLProtoImplProperty::InstallMember(JSContext *aCx,
MOZ_ASSERT(mGetter.IsCompiled() && mSetter.IsCompiled());
MOZ_ASSERT(js::IsObjectInContextCompartment(aTargetClassObject, aCx));
JS::Rooted<JSObject*> globalObject(aCx, JS_GetGlobalForObject(aCx, aTargetClassObject));
MOZ_ASSERT(xpc::IsInXBLScope(globalObject) ||
MOZ_ASSERT(xpc::IsInContentXBLScope(globalObject) ||
globalObject == xpc::GetXBLScope(aCx, globalObject));
JS::Rooted<JSObject*> getter(aCx, mGetter.GetJSFunction());

View File

@ -39,4 +39,7 @@ RESOURCE_FILES += [
'res/table-remove-row-active.gif',
'res/table-remove-row-hover.gif',
'res/table-remove-row.gif',
'res/text_selection_handle.png',
'res/text_selection_handle@1.5.png',
'res/text_selection_handle@2.png',
]

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -731,6 +731,10 @@ nsEditorEventListener::CleanupDragDropCaret()
nsCOMPtr<nsIPresShell> presShell = GetPresShell();
if (presShell)
{
nsCOMPtr<nsISelectionController> selCon(do_QueryInterface(presShell));
if (selCon) {
selCon->SetCaretEnabled(false);
}
presShell->RestoreCaret();
}

View File

@ -2699,19 +2699,6 @@ public:
GLint GetMaxTextureImageSize() { return mMaxTextureImageSize; }
public:
/**
* Context reset constants.
* These are used to determine who is guilty when a context reset
* happens.
*/
enum ContextResetARB {
CONTEXT_NO_ERROR = 0,
CONTEXT_GUILTY_CONTEXT_RESET_ARB = 0x8253,
CONTEXT_INNOCENT_CONTEXT_RESET_ARB = 0x8254,
CONTEXT_UNKNOWN_CONTEXT_RESET_ARB = 0x8255
};
public:
std::map<GLuint, SharedSurface_GL*> mFBOMapping;

Some files were not shown because too many files have changed in this diff Show More