зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c to b2g-inbound. a=merge
This commit is contained in:
Коммит
875db4dc4a
|
@ -29,6 +29,7 @@
|
||||||
# Build directories for js shell
|
# Build directories for js shell
|
||||||
_DBG\.OBJ/
|
_DBG\.OBJ/
|
||||||
_OPT\.OBJ/
|
_OPT\.OBJ/
|
||||||
|
^js/src/.*-obj/
|
||||||
|
|
||||||
# SpiderMonkey configury
|
# SpiderMonkey configury
|
||||||
^js/src/configure$
|
^js/src/configure$
|
||||||
|
|
3
CLOBBER
3
CLOBBER
|
@ -22,5 +22,4 @@
|
||||||
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
|
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
|
||||||
# don't change CLOBBER for WebIDL changes any more.
|
# don't change CLOBBER for WebIDL changes any more.
|
||||||
|
|
||||||
Bug 904723 (Array.from) needs a clobber once again because of changes to js.msg
|
Bug 973238 part 9 needs clobber due to self-hosted code (bug 1019955).
|
||||||
and self-hosted code (see bug 1019955).
|
|
||||||
|
|
|
@ -955,9 +955,14 @@ pref("apz.axis_lock_mode", 2);
|
||||||
pref("apz.subframe.enabled", true);
|
pref("apz.subframe.enabled", true);
|
||||||
|
|
||||||
// Overscroll-related settings
|
// Overscroll-related settings
|
||||||
pref("apz.overscroll.enabled", false);
|
pref("apz.overscroll.enabled", true);
|
||||||
pref("apz.overscroll.snap_back_accel", "0.003");
|
pref("apz.overscroll.fling_friction", "0.02");
|
||||||
pref("apz.overscroll.snap_back_init_vel", "1");
|
pref("apz.overscroll.fling_stopped_threshold", "0.4");
|
||||||
|
pref("apz.overscroll.clamping", "0.5");
|
||||||
|
pref("apz.overscroll.z_effect", "0.2");
|
||||||
|
pref("apz.overscroll.snap_back.spring_stiffness", "0.6");
|
||||||
|
pref("apz.overscroll.snap_back.spring_friction", "0.1");
|
||||||
|
pref("apz.overscroll.snap_back.mass", "1000");
|
||||||
|
|
||||||
// This preference allows FirefoxOS apps (and content, I think) to force
|
// This preference allows FirefoxOS apps (and content, I think) to force
|
||||||
// the use of software (instead of hardware accelerated) 2D canvases by
|
// the use of software (instead of hardware accelerated) 2D canvases by
|
||||||
|
|
|
@ -650,7 +650,7 @@ let settingsToObserve = {
|
||||||
prefName: 'dom.browser_frames.useAsyncPanZoom',
|
prefName: 'dom.browser_frames.useAsyncPanZoom',
|
||||||
defaultValue: false
|
defaultValue: false
|
||||||
},
|
},
|
||||||
'apz.overscroll.enabled': false,
|
'apz.overscroll.enabled': true,
|
||||||
'debug.fps.enabled': {
|
'debug.fps.enabled': {
|
||||||
prefName: 'layers.acceleration.draw-fps',
|
prefName: 'layers.acceleration.draw-fps',
|
||||||
defaultValue: false
|
defaultValue: false
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
[DEFAULT]
|
[DEFAULT]
|
||||||
|
run-if = toolkit == "gonk"
|
||||||
support-files =
|
support-files =
|
||||||
permission_handler_chrome.js
|
permission_handler_chrome.js
|
||||||
SandboxPromptTest.html
|
SandboxPromptTest.html
|
||||||
|
@ -6,11 +7,8 @@ support-files =
|
||||||
systemapp_helper.js
|
systemapp_helper.js
|
||||||
|
|
||||||
[test_sandbox_permission.html]
|
[test_sandbox_permission.html]
|
||||||
run-if = toolkit == "gonk"
|
skip-if = true # bug 984274 - frequent timeouts
|
||||||
[test_filepicker_path.html]
|
[test_filepicker_path.html]
|
||||||
run-if = toolkit == "gonk"
|
|
||||||
[test_permission_deny.html]
|
[test_permission_deny.html]
|
||||||
run-if = toolkit == "gonk"
|
|
||||||
[test_permission_gum_remember.html]
|
[test_permission_gum_remember.html]
|
||||||
run-if = toolkit == "gonk"
|
|
||||||
[test_systemapp.html]
|
[test_systemapp.html]
|
||||||
|
|
|
@ -486,6 +486,8 @@
|
||||||
@BINPATH@/components/nsFormHistory.js
|
@BINPATH@/components/nsFormHistory.js
|
||||||
@BINPATH@/components/FormHistoryStartup.js
|
@BINPATH@/components/FormHistoryStartup.js
|
||||||
@BINPATH@/components/nsInputListAutoComplete.js
|
@BINPATH@/components/nsInputListAutoComplete.js
|
||||||
|
@BINPATH@/components/formautofill.manifest
|
||||||
|
@BINPATH@/components/AutofillController.js
|
||||||
@BINPATH@/components/contentSecurityPolicy.manifest
|
@BINPATH@/components/contentSecurityPolicy.manifest
|
||||||
@BINPATH@/components/contentSecurityPolicy.js
|
@BINPATH@/components/contentSecurityPolicy.js
|
||||||
@BINPATH@/components/contentAreaDropListener.manifest
|
@BINPATH@/components/contentAreaDropListener.manifest
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1400782040000">
|
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1401837170000">
|
||||||
<emItems>
|
<emItems>
|
||||||
<emItem blockID="i454" id="sqlmoz@facebook.com">
|
<emItem blockID="i454" id="sqlmoz@facebook.com">
|
||||||
<versionRange minVersion="0" maxVersion="*" severity="3">
|
<versionRange minVersion="0" maxVersion="*" severity="3">
|
||||||
|
@ -871,6 +871,12 @@
|
||||||
<emItem blockID="i43" id="supportaccessplugin@gmail.com">
|
<emItem blockID="i43" id="supportaccessplugin@gmail.com">
|
||||||
<prefs>
|
<prefs>
|
||||||
</prefs>
|
</prefs>
|
||||||
|
</emItem>
|
||||||
|
<emItem blockID="i588" id="quick_start@gmail.com">
|
||||||
|
<versionRange minVersion="0" maxVersion="*" severity="3">
|
||||||
|
</versionRange>
|
||||||
|
<prefs>
|
||||||
|
</prefs>
|
||||||
</emItem>
|
</emItem>
|
||||||
<emItem blockID="i340" id="chiang@programmer.net">
|
<emItem blockID="i340" id="chiang@programmer.net">
|
||||||
<versionRange minVersion="0" maxVersion="*" severity="3">
|
<versionRange minVersion="0" maxVersion="*" severity="3">
|
||||||
|
@ -1278,8 +1284,8 @@
|
||||||
<prefs>
|
<prefs>
|
||||||
</prefs>
|
</prefs>
|
||||||
</emItem>
|
</emItem>
|
||||||
<emItem blockID="i19" id="{46551EC9-40F0-4e47-8E18-8E5CF550CFB8}">
|
<emItem blockID="i586" id="jid1-0xtMKhXFEs4jIg@jetpack">
|
||||||
<versionRange minVersion="1.1b1" maxVersion="1.1b1">
|
<versionRange minVersion="0" maxVersion="*" severity="3">
|
||||||
</versionRange>
|
</versionRange>
|
||||||
<prefs>
|
<prefs>
|
||||||
</prefs>
|
</prefs>
|
||||||
|
@ -1289,6 +1295,12 @@
|
||||||
</versionRange>
|
</versionRange>
|
||||||
<prefs>
|
<prefs>
|
||||||
</prefs>
|
</prefs>
|
||||||
|
</emItem>
|
||||||
|
<emItem blockID="i19" id="{46551EC9-40F0-4e47-8E18-8E5CF550CFB8}">
|
||||||
|
<versionRange minVersion="1.1b1" maxVersion="1.1b1">
|
||||||
|
</versionRange>
|
||||||
|
<prefs>
|
||||||
|
</prefs>
|
||||||
</emItem>
|
</emItem>
|
||||||
<emItem blockID="i531" id="/^(4cb61367-efbf-4aa1-8e3a-7f776c9d5763@cdece6e9-b2ef-40a9-b178-291da9870c59\.com|0efc9c38-1ec7-49ed-8915-53a48b6b7600@e7f17679-2a42-4659-83c5-7ba961fdf75a\.com|6be3335b-ef79-4b0b-a0ba-b87afbc6f4ad@6bbb4d2e-e33e-4fa5-9b37-934f4fb50182\.com)$/">
|
<emItem blockID="i531" id="/^(4cb61367-efbf-4aa1-8e3a-7f776c9d5763@cdece6e9-b2ef-40a9-b178-291da9870c59\.com|0efc9c38-1ec7-49ed-8915-53a48b6b7600@e7f17679-2a42-4659-83c5-7ba961fdf75a\.com|6be3335b-ef79-4b0b-a0ba-b87afbc6f4ad@6bbb4d2e-e33e-4fa5-9b37-934f4fb50182\.com)$/">
|
||||||
<versionRange minVersion="0" maxVersion="*" severity="1">
|
<versionRange minVersion="0" maxVersion="*" severity="1">
|
||||||
|
@ -1409,6 +1421,12 @@
|
||||||
</versionRange>
|
</versionRange>
|
||||||
<prefs>
|
<prefs>
|
||||||
</prefs>
|
</prefs>
|
||||||
|
</emItem>
|
||||||
|
<emItem blockID="i590" id="{94cd2cc3-083f-49ba-a218-4cda4b4829fd}">
|
||||||
|
<versionRange minVersion="0" maxVersion="*" severity="1">
|
||||||
|
</versionRange>
|
||||||
|
<prefs>
|
||||||
|
</prefs>
|
||||||
</emItem>
|
</emItem>
|
||||||
<emItem blockID="i544" id="/^(93abedcf-8e3a-4d02-b761-d1441e437c09@243f129d-aee2-42c2-bcd1-48858e1c22fd\.com|9acfc440-ac2d-417a-a64c-f6f14653b712@09f9a966-9258-4b12-af32-da29bdcc28c5\.com|58ad0086-1cfb-48bb-8ad2-33a8905572bc@5715d2be-69b9-4930-8f7e-64bdeb961cfd\.com)$/">
|
<emItem blockID="i544" id="/^(93abedcf-8e3a-4d02-b761-d1441e437c09@243f129d-aee2-42c2-bcd1-48858e1c22fd\.com|9acfc440-ac2d-417a-a64c-f6f14653b712@09f9a966-9258-4b12-af32-da29bdcc28c5\.com|58ad0086-1cfb-48bb-8ad2-33a8905572bc@5715d2be-69b9-4930-8f7e-64bdeb961cfd\.com)$/">
|
||||||
<versionRange minVersion="0" maxVersion="*" severity="1">
|
<versionRange minVersion="0" maxVersion="*" severity="1">
|
||||||
|
|
|
@ -1237,8 +1237,12 @@ pref("devtools.appmanager.enabled", true);
|
||||||
pref("devtools.appmanager.lastTab", "help");
|
pref("devtools.appmanager.lastTab", "help");
|
||||||
pref("devtools.appmanager.manifestEditor.enabled", true);
|
pref("devtools.appmanager.manifestEditor.enabled", true);
|
||||||
|
|
||||||
// Disable devtools webide until bug 1007059
|
// Enable devtools webide
|
||||||
|
#ifdef MOZ_DEVTOOLS_WEBIDE
|
||||||
|
pref("devtools.webide.enabled", true);
|
||||||
|
#else
|
||||||
pref("devtools.webide.enabled", false);
|
pref("devtools.webide.enabled", false);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Toolbox preferences
|
// Toolbox preferences
|
||||||
pref("devtools.toolbox.footer.height", 250);
|
pref("devtools.toolbox.footer.height", 250);
|
||||||
|
@ -1561,6 +1565,8 @@ pref("identity.fxaccounts.settings.uri", "https://accounts.firefox.com/settings"
|
||||||
pref("ui.key.menuAccessKeyFocuses", true);
|
pref("ui.key.menuAccessKeyFocuses", true);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Encrypted media extensions.
|
||||||
|
pref("media.eme.enabled", false);
|
||||||
|
|
||||||
// Delete HTTP cache v2 data of users that didn't opt-in manually
|
// Delete HTTP cache v2 data of users that didn't opt-in manually
|
||||||
pref("browser.cache.auto_delete_cache_version", 1);
|
pref("browser.cache.auto_delete_cache_version", 1);
|
||||||
|
|
|
@ -445,7 +445,7 @@ nsContextMenu.prototype = {
|
||||||
this.showItem("context-media-showcontrols", onMedia && !this.target.controls);
|
this.showItem("context-media-showcontrols", onMedia && !this.target.controls);
|
||||||
this.showItem("context-media-hidecontrols", onMedia && this.target.controls);
|
this.showItem("context-media-hidecontrols", onMedia && this.target.controls);
|
||||||
this.showItem("context-video-fullscreen", this.onVideo && this.target.ownerDocument.mozFullScreenElement == null);
|
this.showItem("context-video-fullscreen", this.onVideo && this.target.ownerDocument.mozFullScreenElement == null);
|
||||||
var statsShowing = this.onVideo && XPCNativeWrapper.unwrap(this.target).mozMediaStatisticsShowing;
|
var statsShowing = this.onVideo && this.target.mozMediaStatisticsShowing;
|
||||||
this.showItem("context-video-showstats", this.onVideo && this.target.controls && !statsShowing);
|
this.showItem("context-video-showstats", this.onVideo && this.target.controls && !statsShowing);
|
||||||
this.showItem("context-video-hidestats", this.onVideo && this.target.controls && statsShowing);
|
this.showItem("context-video-hidestats", this.onVideo && this.target.controls && statsShowing);
|
||||||
|
|
||||||
|
|
|
@ -28,9 +28,11 @@ DIRS += [
|
||||||
'tilt',
|
'tilt',
|
||||||
'webaudioeditor',
|
'webaudioeditor',
|
||||||
'webconsole',
|
'webconsole',
|
||||||
'webide',
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
if CONFIG['MOZ_DEVTOOLS_WEBIDE']:
|
||||||
|
DIRS += ['webide']
|
||||||
|
|
||||||
EXTRA_COMPONENTS += [
|
EXTRA_COMPONENTS += [
|
||||||
'devtools-clhandler.js',
|
'devtools-clhandler.js',
|
||||||
'devtools-clhandler.manifest',
|
'devtools-clhandler.manifest',
|
||||||
|
|
|
@ -157,14 +157,12 @@ let UI = {
|
||||||
unbusy: function() {
|
unbusy: function() {
|
||||||
document.querySelector("window").classList.remove("busy")
|
document.querySelector("window").classList.remove("busy")
|
||||||
this.updateCommands();
|
this.updateCommands();
|
||||||
this._busyPromise = null;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
busyUntil: function(promise, operationDescription) {
|
busyUntil: function(promise, operationDescription) {
|
||||||
// Freeze the UI until the promise is resolved. A 30s timeout
|
// Freeze the UI until the promise is resolved. A 30s timeout
|
||||||
// will unfreeze the UI, just in case the promise never gets
|
// will unfreeze the UI, just in case the promise never gets
|
||||||
// resolved.
|
// resolved.
|
||||||
this._busyPromise = promise;
|
|
||||||
let timeout = setTimeout(() => {
|
let timeout = setTimeout(() => {
|
||||||
this.unbusy();
|
this.unbusy();
|
||||||
UI.reportError("error_operationTimeout", operationDescription);
|
UI.reportError("error_operationTimeout", operationDescription);
|
||||||
|
|
|
@ -62,15 +62,17 @@ function closeWebIDE(win) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeAllProjects() {
|
function removeAllProjects() {
|
||||||
return Task.spawn(function* () {
|
let deferred = promise.defer();
|
||||||
yield AppProjects.load();
|
AppProjects.load().then(() => {
|
||||||
let projects = AppProjects.store.object.projects;
|
let projects = AppProjects.store.object.projects;
|
||||||
for (let i = 0; i < projects.length; i++) {
|
for (let i = 0; i < projects.length; i++) {
|
||||||
yield AppProjects.remove(projects[i].location);
|
AppProjects.remove(projects[i].location);
|
||||||
}
|
}
|
||||||
|
deferred.resolve();
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
|
return deferred.promise;
|
||||||
|
}
|
||||||
function nextTick() {
|
function nextTick() {
|
||||||
let deferred = promise.defer();
|
let deferred = promise.defer();
|
||||||
SimpleTest.executeSoon(() => {
|
SimpleTest.executeSoon(() => {
|
||||||
|
|
|
@ -19,12 +19,15 @@
|
||||||
SimpleTest.waitForExplicitFinish();
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
|
||||||
Task.spawn(function* () {
|
Task.spawn(function* () {
|
||||||
|
let clClass = Components.classes["@mozilla.org/toolkit/command-line;1"].createInstance();
|
||||||
|
|
||||||
Cu.import("resource://gre/modules/devtools/dbg-server.jsm");
|
Cu.import("resource://gre/modules/devtools/dbg-server.jsm");
|
||||||
DebuggerServer.init(function () { return true; });
|
DebuggerServer.init(function () { return true; });
|
||||||
DebuggerServer.addBrowserActors();
|
DebuggerServer.addBrowserActors();
|
||||||
|
|
||||||
let win = yield openWebIDE();
|
let win = yield openWebIDE();
|
||||||
|
|
||||||
|
|
||||||
let packagedAppLocation = getTestFilePath("app");
|
let packagedAppLocation = getTestFilePath("app");
|
||||||
|
|
||||||
let cli = "actions=addPackagedApp&location=" + packagedAppLocation;
|
let cli = "actions=addPackagedApp&location=" + packagedAppLocation;
|
||||||
|
|
|
@ -22,9 +22,6 @@
|
||||||
let win = yield openWebIDE();
|
let win = yield openWebIDE();
|
||||||
let packagedAppLocation = getTestFilePath("app");
|
let packagedAppLocation = getTestFilePath("app");
|
||||||
|
|
||||||
yield win.AppProjects.load();
|
|
||||||
is(win.AppProjects.store.object.projects.length, 0, "IDB is empty");
|
|
||||||
|
|
||||||
yield win.Cmds.importPackagedApp(packagedAppLocation);
|
yield win.Cmds.importPackagedApp(packagedAppLocation);
|
||||||
|
|
||||||
let project = win.AppManager.selectedProject;
|
let project = win.AppManager.selectedProject;
|
||||||
|
|
|
@ -49,9 +49,10 @@
|
||||||
|
|
||||||
win.AppManager.update("runtimelist");
|
win.AppManager.update("runtimelist");
|
||||||
|
|
||||||
let packagedAppLocation = getTestFilePath("app");
|
let hostedAppManifest = TEST_BASE + "hosted_app.manifest";
|
||||||
|
yield win.Cmds.importHostedApp(hostedAppManifest);
|
||||||
|
|
||||||
yield win.Cmds.importPackagedApp(packagedAppLocation);
|
yield win.Cmds.showRuntimePanel();
|
||||||
|
|
||||||
let panelNode = win.document.querySelector("#runtime-panel");
|
let panelNode = win.document.querySelector("#runtime-panel");
|
||||||
let items = panelNode.querySelectorAll(".runtime-panel-item-usb");
|
let items = panelNode.querySelectorAll(".runtime-panel-item-usb");
|
||||||
|
@ -64,27 +65,36 @@
|
||||||
|
|
||||||
items[0].click();
|
items[0].click();
|
||||||
|
|
||||||
ok(win.document.querySelector("window").className, "busy", "UI is busy");
|
yield deferred.promise;
|
||||||
yield win.UI._busyPromise;
|
|
||||||
|
|
||||||
is(Object.keys(DebuggerServer._connections).length, 1, "Connected");
|
is(Object.keys(DebuggerServer._connections).length, 1, "Connected");
|
||||||
|
|
||||||
ok(isPlayActive(), "play button is enabled 1");
|
|
||||||
ok(!isStopActive(), "stop button is disabled 1");
|
|
||||||
let oldProject = win.AppManager.selectedProject;
|
|
||||||
win.AppManager.selectedProject = null;
|
|
||||||
|
|
||||||
yield nextTick();
|
yield nextTick();
|
||||||
|
|
||||||
ok(!isPlayActive(), "play button is disabled 2");
|
ok(!isPlayActive(), "play button is disabled 2");
|
||||||
ok(!isStopActive(), "stop button is disabled 2");
|
ok(!isStopActive(), "stop button is disabled 2");
|
||||||
win.AppManager._selectedProject = oldProject;
|
|
||||||
|
win.AppManager.selectedProject.errorsCount = 0;
|
||||||
win.UI.updateCommands();
|
win.UI.updateCommands();
|
||||||
|
|
||||||
yield nextTick();
|
yield nextTick();
|
||||||
|
|
||||||
ok(isPlayActive(), "play button is enabled 3");
|
ok(isPlayActive(), "play button is enabled 3");
|
||||||
ok(!isStopActive(), "stop button is disabled 3");
|
ok(!isStopActive(), "stop button is disabled 3");
|
||||||
|
let oldProject = win.AppManager.selectedProject;
|
||||||
|
win.AppManager.selectedProject = null;
|
||||||
|
|
||||||
|
yield nextTick();
|
||||||
|
|
||||||
|
ok(!isPlayActive(), "play button is disabled 4");
|
||||||
|
ok(!isStopActive(), "stop button is disabled 4");
|
||||||
|
win.AppManager._selectedProject = oldProject;
|
||||||
|
win.UI.updateCommands();
|
||||||
|
|
||||||
|
yield nextTick();
|
||||||
|
|
||||||
|
ok(isPlayActive(), "play button is enabled 5");
|
||||||
|
ok(!isStopActive(), "stop button is disabled 5");
|
||||||
|
|
||||||
|
|
||||||
yield win.Cmds.disconnectRuntime();
|
yield win.Cmds.disconnectRuntime();
|
||||||
|
@ -92,8 +102,8 @@
|
||||||
is(Object.keys(DebuggerServer._connections).length, 0, "Disconnected");
|
is(Object.keys(DebuggerServer._connections).length, 0, "Disconnected");
|
||||||
|
|
||||||
ok(win.AppManager.selectedProject, "A project is still selected");
|
ok(win.AppManager.selectedProject, "A project is still selected");
|
||||||
ok(!isPlayActive(), "play button is disabled 4");
|
ok(!isPlayActive(), "play button is disabled 6");
|
||||||
ok(!isStopActive(), "stop button is disabled 4");
|
ok(!isStopActive(), "stop button is disabled 6");
|
||||||
|
|
||||||
deferred = promise.defer();
|
deferred = promise.defer();
|
||||||
win.AppManager.connection.once(
|
win.AppManager.connection.once(
|
||||||
|
@ -112,8 +122,6 @@
|
||||||
|
|
||||||
DebuggerServer.destroy();
|
DebuggerServer.destroy();
|
||||||
|
|
||||||
yield removeAllProjects();
|
|
||||||
|
|
||||||
SimpleTest.finish();
|
SimpleTest.finish();
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -454,6 +454,8 @@
|
||||||
@BINPATH@/components/nsFormHistory.js
|
@BINPATH@/components/nsFormHistory.js
|
||||||
@BINPATH@/components/FormHistoryStartup.js
|
@BINPATH@/components/FormHistoryStartup.js
|
||||||
@BINPATH@/components/nsInputListAutoComplete.js
|
@BINPATH@/components/nsInputListAutoComplete.js
|
||||||
|
@BINPATH@/components/formautofill.manifest
|
||||||
|
@BINPATH@/components/AutofillController.js
|
||||||
@BINPATH@/components/contentSecurityPolicy.manifest
|
@BINPATH@/components/contentSecurityPolicy.manifest
|
||||||
@BINPATH@/components/contentSecurityPolicy.js
|
@BINPATH@/components/contentSecurityPolicy.js
|
||||||
@BINPATH@/components/contentAreaDropListener.manifest
|
@BINPATH@/components/contentAreaDropListener.manifest
|
||||||
|
@ -636,9 +638,11 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
; [Webide Files]
|
; [Webide Files]
|
||||||
|
#ifdef MOZ_DEVTOOLS_WEBIDE
|
||||||
@BINPATH@/browser/chrome/webide@JAREXT@
|
@BINPATH@/browser/chrome/webide@JAREXT@
|
||||||
@BINPATH@/browser/chrome/webide.manifest
|
@BINPATH@/browser/chrome/webide.manifest
|
||||||
@BINPATH@/browser/@PREF_DIR@/webide-prefs.js
|
@BINPATH@/browser/@PREF_DIR@/webide-prefs.js
|
||||||
|
#endif
|
||||||
|
|
||||||
; shell icons
|
; shell icons
|
||||||
#ifdef XP_UNIX
|
#ifdef XP_UNIX
|
||||||
|
|
|
@ -510,6 +510,8 @@
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: 0, 1px, 2px;
|
background-position: 0, 1px, 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#toolbox-buttons:empty + #toolbox-controls-separator,
|
||||||
#toolbox-controls-separator[invisible] {
|
#toolbox-controls-separator[invisible] {
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
}
|
}
|
||||||
|
|
13
configure.in
13
configure.in
|
@ -7680,6 +7680,19 @@ if test "$MOZ_CHROME_FILE_FORMAT" != "jar" &&
|
||||||
AC_MSG_ERROR([--enable-chrome-format must be set to either jar, flat, or omni])
|
AC_MSG_ERROR([--enable-chrome-format must be set to either jar, flat, or omni])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
dnl ========================================================
|
||||||
|
dnl = Enable Support for devtools webide
|
||||||
|
dnl ========================================================
|
||||||
|
MOZ_ARG_ENABLE_BOOL(devtools-webide,
|
||||||
|
[ --enable-devtools-webide Set compile flags necessary for compiling devtools webide ],
|
||||||
|
MOZ_DEVTOOLS_WEBIDE=1,
|
||||||
|
MOZ_DEVTOOLS_WEBIDE= )
|
||||||
|
|
||||||
|
if test -n "$MOZ_DEVTOOLS_WEBIDE"; then
|
||||||
|
AC_DEFINE(MOZ_DEVTOOLS_WEBIDE)
|
||||||
|
fi
|
||||||
|
AC_SUBST(MOZ_DEVTOOLS_WEBIDE)
|
||||||
|
|
||||||
dnl =========================================================
|
dnl =========================================================
|
||||||
dnl Omnijar packaging (bug 552121)
|
dnl Omnijar packaging (bug 552121)
|
||||||
dnl =========================================================
|
dnl =========================================================
|
||||||
|
|
|
@ -883,10 +883,10 @@ public:
|
||||||
*/
|
*/
|
||||||
nsIFrame* GetPrimaryFrame() const
|
nsIFrame* GetPrimaryFrame() const
|
||||||
{
|
{
|
||||||
return IsInDoc() ? mPrimaryFrame : nullptr;
|
return (IsInDoc() || HasFlag(NODE_IS_IN_SHADOW_TREE)) ? mPrimaryFrame : nullptr;
|
||||||
}
|
}
|
||||||
void SetPrimaryFrame(nsIFrame* aFrame) {
|
void SetPrimaryFrame(nsIFrame* aFrame) {
|
||||||
NS_ASSERTION(IsInDoc(), "This will end badly!");
|
MOZ_ASSERT(IsInDoc() || HasFlag(NODE_IS_IN_SHADOW_TREE), "This will end badly!");
|
||||||
NS_PRECONDITION(!aFrame || !mPrimaryFrame || aFrame == mPrimaryFrame,
|
NS_PRECONDITION(!aFrame || !mPrimaryFrame || aFrame == mPrimaryFrame,
|
||||||
"Losing track of existing primary frame");
|
"Losing track of existing primary frame");
|
||||||
mPrimaryFrame = aFrame;
|
mPrimaryFrame = aFrame;
|
||||||
|
|
|
@ -525,6 +525,19 @@ public:
|
||||||
return IsInDoc() ? OwnerDoc() : nullptr;
|
return IsInDoc() ? OwnerDoc() : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method gets the current doc of the node hosting this content
|
||||||
|
* or the current doc of this content if it is not being hosted. This
|
||||||
|
* method walks through ShadowRoot boundaries until it reach the host
|
||||||
|
* that is located in the root of the "tree of trees" (see Shadow DOM
|
||||||
|
* spec) and returns the current doc for that host.
|
||||||
|
*/
|
||||||
|
nsIDocument* GetCrossShadowCurrentDoc() const
|
||||||
|
{
|
||||||
|
return HasFlag(NODE_IS_IN_SHADOW_TREE) ?
|
||||||
|
GetCrossShadowCurrentDocInternal() : GetCurrentDoc();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The values returned by this function are the ones defined for
|
* The values returned by this function are the ones defined for
|
||||||
* nsIDOMNode.nodeType
|
* nsIDOMNode.nodeType
|
||||||
|
@ -808,29 +821,7 @@ public:
|
||||||
* null. It may return 'this' (e.g. for document nodes, and nodes that
|
* null. It may return 'this' (e.g. for document nodes, and nodes that
|
||||||
* are the roots of disconnected subtrees).
|
* are the roots of disconnected subtrees).
|
||||||
*/
|
*/
|
||||||
nsINode* SubtreeRoot() const
|
nsINode* SubtreeRoot() const;
|
||||||
{
|
|
||||||
// There are three cases of interest here. nsINodes that are really:
|
|
||||||
// 1. nsIDocument nodes - Are always in the document.
|
|
||||||
// 2. nsIContent nodes - Are either in the document, or mSubtreeRoot
|
|
||||||
// is updated in BindToTree/UnbindFromTree.
|
|
||||||
// 3. nsIAttribute nodes - Are never in the document, and mSubtreeRoot
|
|
||||||
// is always 'this' (as set in nsINode's ctor).
|
|
||||||
nsINode* node = IsInDoc() ? OwnerDocAsNode() : mSubtreeRoot;
|
|
||||||
NS_ASSERTION(node, "Should always have a node here!");
|
|
||||||
#ifdef DEBUG
|
|
||||||
{
|
|
||||||
const nsINode* slowNode = this;
|
|
||||||
const nsINode* iter = slowNode;
|
|
||||||
while ((iter = iter->GetParentNode())) {
|
|
||||||
slowNode = iter;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_ASSERTION(slowNode == node, "These should always be in sync!");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See nsIDOMEventTarget
|
* See nsIDOMEventTarget
|
||||||
|
@ -1205,6 +1196,8 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
nsIDocument* GetCrossShadowCurrentDocInternal() const;
|
||||||
|
|
||||||
nsIContent* GetNextNodeImpl(const nsINode* aRoot,
|
nsIContent* GetNextNodeImpl(const nsINode* aRoot,
|
||||||
const bool aSkipChildren) const
|
const bool aSkipChildren) const
|
||||||
{
|
{
|
||||||
|
@ -1520,7 +1513,8 @@ protected:
|
||||||
void SetSubtreeRootPointer(nsINode* aSubtreeRoot)
|
void SetSubtreeRootPointer(nsINode* aSubtreeRoot)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(aSubtreeRoot, "aSubtreeRoot can never be null!");
|
NS_ASSERTION(aSubtreeRoot, "aSubtreeRoot can never be null!");
|
||||||
NS_ASSERTION(!(IsNodeOfType(eCONTENT) && IsInDoc()), "Shouldn't be here!");
|
NS_ASSERTION(!(IsNodeOfType(eCONTENT) && IsInDoc()) &&
|
||||||
|
!HasFlag(NODE_IS_IN_SHADOW_TREE), "Shouldn't be here!");
|
||||||
mSubtreeRoot = aSubtreeRoot;
|
mSubtreeRoot = aSubtreeRoot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -190,7 +190,7 @@ Element::IntrinsicState() const
|
||||||
void
|
void
|
||||||
Element::NotifyStateChange(EventStates aStates)
|
Element::NotifyStateChange(EventStates aStates)
|
||||||
{
|
{
|
||||||
nsIDocument* doc = GetCurrentDoc();
|
nsIDocument* doc = GetCrossShadowCurrentDoc();
|
||||||
if (doc) {
|
if (doc) {
|
||||||
nsAutoScriptBlocker scriptBlocker;
|
nsAutoScriptBlocker scriptBlocker;
|
||||||
doc->ContentStateChanged(this, aStates);
|
doc->ContentStateChanged(this, aStates);
|
||||||
|
@ -831,7 +831,7 @@ Element::CreateShadowRoot(ErrorResult& aError)
|
||||||
|
|
||||||
// Recreate the frame for the bound content because binding a ShadowRoot
|
// Recreate the frame for the bound content because binding a ShadowRoot
|
||||||
// changes how things are rendered.
|
// changes how things are rendered.
|
||||||
nsIDocument* doc = GetCurrentDoc();
|
nsIDocument* doc = GetCrossShadowCurrentDoc();
|
||||||
if (doc) {
|
if (doc) {
|
||||||
nsIPresShell *shell = doc->GetShell();
|
nsIPresShell *shell = doc->GetShell();
|
||||||
if (shell) {
|
if (shell) {
|
||||||
|
@ -1231,6 +1231,7 @@ Element::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||||
SetFlags(NODE_CHROME_ONLY_ACCESS);
|
SetFlags(NODE_CHROME_ONLY_ACCESS);
|
||||||
}
|
}
|
||||||
if (aParent->HasFlag(NODE_IS_IN_SHADOW_TREE)) {
|
if (aParent->HasFlag(NODE_IS_IN_SHADOW_TREE)) {
|
||||||
|
ClearSubtreeRootPointer();
|
||||||
SetFlags(NODE_IS_IN_SHADOW_TREE);
|
SetFlags(NODE_IS_IN_SHADOW_TREE);
|
||||||
}
|
}
|
||||||
ShadowRoot* parentContainingShadow = aParent->GetContainingShadow();
|
ShadowRoot* parentContainingShadow = aParent->GetContainingShadow();
|
||||||
|
@ -1291,8 +1292,9 @@ Element::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||||
|
|
||||||
// Propagate scoped style sheet tracking bit.
|
// Propagate scoped style sheet tracking bit.
|
||||||
SetIsElementInStyleScope(mParent->IsElementInStyleScope());
|
SetIsElementInStyleScope(mParent->IsElementInStyleScope());
|
||||||
} else {
|
} else if (!HasFlag(NODE_IS_IN_SHADOW_TREE)) {
|
||||||
// If we're not in the doc, update our subtree pointer.
|
// If we're not in the doc and not in a shadow tree,
|
||||||
|
// update our subtree pointer.
|
||||||
SetSubtreeRootPointer(aParent->SubtreeRoot());
|
SetSubtreeRootPointer(aParent->SubtreeRoot());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1435,6 +1437,7 @@ Element::UnbindFromTree(bool aDeep, bool aNullParent)
|
||||||
SetParentIsContent(false);
|
SetParentIsContent(false);
|
||||||
}
|
}
|
||||||
ClearInDocument();
|
ClearInDocument();
|
||||||
|
UnsetFlags(NODE_IS_IN_SHADOW_TREE);
|
||||||
|
|
||||||
// Begin keeping track of our subtree root.
|
// Begin keeping track of our subtree root.
|
||||||
SetSubtreeRootPointer(aNullParent ? this : mParent->SubtreeRoot());
|
SetSubtreeRootPointer(aNullParent ? this : mParent->SubtreeRoot());
|
||||||
|
@ -1470,7 +1473,7 @@ Element::UnbindFromTree(bool aDeep, bool aNullParent)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unset this since that's what the old code effectively did.
|
// Unset this since that's what the old code effectively did.
|
||||||
UnsetFlags(NODE_FORCE_XBL_BINDINGS | NODE_IS_IN_SHADOW_TREE);
|
UnsetFlags(NODE_FORCE_XBL_BINDINGS);
|
||||||
|
|
||||||
#ifdef MOZ_XUL
|
#ifdef MOZ_XUL
|
||||||
nsXULElement* xulElem = nsXULElement::FromContent(this);
|
nsXULElement* xulElem = nsXULElement::FromContent(this);
|
||||||
|
|
|
@ -72,9 +72,14 @@ ShadowRoot::ShadowRoot(nsIContent* aContent,
|
||||||
mInsertionPointChanged(false)
|
mInsertionPointChanged(false)
|
||||||
{
|
{
|
||||||
SetHost(aContent);
|
SetHost(aContent);
|
||||||
|
|
||||||
|
// Nodes in a shadow tree should never store a value
|
||||||
|
// in the subtree root pointer, nodes in the shadow tree
|
||||||
|
// track the subtree root using GetContainingShadow().
|
||||||
|
ClearSubtreeRootPointer();
|
||||||
|
|
||||||
SetFlags(NODE_IS_IN_SHADOW_TREE);
|
SetFlags(NODE_IS_IN_SHADOW_TREE);
|
||||||
// ShadowRoot isn't really in the document but it behaves like it is.
|
|
||||||
SetInDocument();
|
|
||||||
DOMSlots()->mBindingParent = aContent;
|
DOMSlots()->mBindingParent = aContent;
|
||||||
DOMSlots()->mContainingShadow = this;
|
DOMSlots()->mContainingShadow = this;
|
||||||
|
|
||||||
|
@ -92,7 +97,11 @@ ShadowRoot::~ShadowRoot()
|
||||||
mPoolHost->RemoveMutationObserver(this);
|
mPoolHost->RemoveMutationObserver(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
ClearInDocument();
|
UnsetFlags(NODE_IS_IN_SHADOW_TREE);
|
||||||
|
|
||||||
|
// nsINode destructor expects mSubtreeRoot == this.
|
||||||
|
SetSubtreeRootPointer(this);
|
||||||
|
|
||||||
SetHost(nullptr);
|
SetHost(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,14 +124,14 @@ ShadowRoot::FromNode(nsINode* aNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ShadowRoot::Restyle()
|
ShadowRoot::StyleSheetChanged()
|
||||||
{
|
{
|
||||||
mProtoBinding->FlushSkinSheets();
|
mProtoBinding->FlushSkinSheets();
|
||||||
|
|
||||||
nsIPresShell* shell = OwnerDoc()->GetShell();
|
nsIPresShell* shell = OwnerDoc()->GetShell();
|
||||||
if (shell) {
|
if (shell) {
|
||||||
OwnerDoc()->BeginUpdate(UPDATE_STYLE);
|
OwnerDoc()->BeginUpdate(UPDATE_STYLE);
|
||||||
shell->RestyleShadowRoot(this);
|
shell->RecordShadowStyleChange(this);
|
||||||
OwnerDoc()->EndUpdate(UPDATE_STYLE);
|
OwnerDoc()->EndUpdate(UPDATE_STYLE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -157,7 +166,9 @@ ShadowRoot::InsertSheet(nsCSSStyleSheet* aSheet,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Restyle();
|
if (aSheet->IsApplicable()) {
|
||||||
|
StyleSheetChanged();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -171,7 +182,9 @@ ShadowRoot::RemoveSheet(nsCSSStyleSheet* aSheet)
|
||||||
MOZ_ASSERT(found, "Trying to remove a sheet from a ShadowRoot "
|
MOZ_ASSERT(found, "Trying to remove a sheet from a ShadowRoot "
|
||||||
"that does not exist.");
|
"that does not exist.");
|
||||||
|
|
||||||
Restyle();
|
if (aSheet->IsApplicable()) {
|
||||||
|
StyleSheetChanged();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Element*
|
Element*
|
||||||
|
@ -494,7 +507,7 @@ ShadowRoot::SetApplyAuthorStyles(bool aApplyAuthorStyles)
|
||||||
nsIPresShell* shell = OwnerDoc()->GetShell();
|
nsIPresShell* shell = OwnerDoc()->GetShell();
|
||||||
if (shell) {
|
if (shell) {
|
||||||
OwnerDoc()->BeginUpdate(UPDATE_STYLE);
|
OwnerDoc()->BeginUpdate(UPDATE_STYLE);
|
||||||
shell->RestyleShadowRoot(this);
|
shell->RecordShadowStyleChange(this);
|
||||||
OwnerDoc()->EndUpdate(UPDATE_STYLE);
|
OwnerDoc()->EndUpdate(UPDATE_STYLE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,8 +127,8 @@ public:
|
||||||
GetElementsByClassName(const nsAString& aClasses);
|
GetElementsByClassName(const nsAString& aClasses);
|
||||||
void GetInnerHTML(nsAString& aInnerHTML);
|
void GetInnerHTML(nsAString& aInnerHTML);
|
||||||
void SetInnerHTML(const nsAString& aInnerHTML, ErrorResult& aError);
|
void SetInnerHTML(const nsAString& aInnerHTML, ErrorResult& aError);
|
||||||
|
void StyleSheetChanged();
|
||||||
protected:
|
protected:
|
||||||
void Restyle();
|
|
||||||
|
|
||||||
// The pool host is the parent of the nodes that will be distributed
|
// The pool host is the parent of the nodes that will be distributed
|
||||||
// into the insertion points in this ShadowRoot. See |ChangeShadowRoot|.
|
// into the insertion points in this ShadowRoot. See |ChangeShadowRoot|.
|
||||||
|
|
|
@ -492,6 +492,7 @@ nsGenericDOMDataNode::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||||
SetFlags(NODE_CHROME_ONLY_ACCESS);
|
SetFlags(NODE_CHROME_ONLY_ACCESS);
|
||||||
}
|
}
|
||||||
if (aParent->HasFlag(NODE_IS_IN_SHADOW_TREE)) {
|
if (aParent->HasFlag(NODE_IS_IN_SHADOW_TREE)) {
|
||||||
|
ClearSubtreeRootPointer();
|
||||||
SetFlags(NODE_IS_IN_SHADOW_TREE);
|
SetFlags(NODE_IS_IN_SHADOW_TREE);
|
||||||
}
|
}
|
||||||
ShadowRoot* parentContainingShadow = aParent->GetContainingShadow();
|
ShadowRoot* parentContainingShadow = aParent->GetContainingShadow();
|
||||||
|
@ -527,8 +528,9 @@ nsGenericDOMDataNode::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||||
}
|
}
|
||||||
// Clear the lazy frame construction bits.
|
// Clear the lazy frame construction bits.
|
||||||
UnsetFlags(NODE_NEEDS_FRAME | NODE_DESCENDANTS_NEED_FRAMES);
|
UnsetFlags(NODE_NEEDS_FRAME | NODE_DESCENDANTS_NEED_FRAMES);
|
||||||
} else {
|
} else if (!HasFlag(NODE_IS_IN_SHADOW_TREE)) {
|
||||||
// If we're not in the doc, update our subtree pointer.
|
// If we're not in the doc and not in a shadow tree,
|
||||||
|
// update our subtree pointer.
|
||||||
SetSubtreeRootPointer(aParent->SubtreeRoot());
|
SetSubtreeRootPointer(aParent->SubtreeRoot());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -549,10 +551,7 @@ nsGenericDOMDataNode::UnbindFromTree(bool aDeep, bool aNullParent)
|
||||||
{
|
{
|
||||||
// Unset frame flags; if we need them again later, they'll get set again.
|
// Unset frame flags; if we need them again later, they'll get set again.
|
||||||
UnsetFlags(NS_CREATE_FRAME_IF_NON_WHITESPACE |
|
UnsetFlags(NS_CREATE_FRAME_IF_NON_WHITESPACE |
|
||||||
NS_REFRAME_IF_WHITESPACE |
|
NS_REFRAME_IF_WHITESPACE);
|
||||||
// Also unset the shadow tree flag because it can
|
|
||||||
// no longer be a descendant of a ShadowRoot.
|
|
||||||
NODE_IS_IN_SHADOW_TREE);
|
|
||||||
|
|
||||||
nsIDocument *document = GetCurrentDoc();
|
nsIDocument *document = GetCurrentDoc();
|
||||||
if (document) {
|
if (document) {
|
||||||
|
@ -571,6 +570,7 @@ nsGenericDOMDataNode::UnbindFromTree(bool aDeep, bool aNullParent)
|
||||||
SetParentIsContent(false);
|
SetParentIsContent(false);
|
||||||
}
|
}
|
||||||
ClearInDocument();
|
ClearInDocument();
|
||||||
|
UnsetFlags(NODE_IS_IN_SHADOW_TREE);
|
||||||
|
|
||||||
// Begin keeping track of our subtree root.
|
// Begin keeping track of our subtree root.
|
||||||
SetSubtreeRootPointer(aNullParent ? this : mParent->SubtreeRoot());
|
SetSubtreeRootPointer(aNullParent ? this : mParent->SubtreeRoot());
|
||||||
|
|
|
@ -497,6 +497,7 @@ GK_ATOM(keydown, "keydown")
|
||||||
GK_ATOM(keygen, "keygen")
|
GK_ATOM(keygen, "keygen")
|
||||||
GK_ATOM(keypress, "keypress")
|
GK_ATOM(keypress, "keypress")
|
||||||
GK_ATOM(keyset, "keyset")
|
GK_ATOM(keyset, "keyset")
|
||||||
|
GK_ATOM(keysystem, "keysystem")
|
||||||
GK_ATOM(keytext, "keytext")
|
GK_ATOM(keytext, "keytext")
|
||||||
GK_ATOM(keyup, "keyup")
|
GK_ATOM(keyup, "keyup")
|
||||||
GK_ATOM(kind, "kind")
|
GK_ATOM(kind, "kind")
|
||||||
|
@ -1944,6 +1945,8 @@ GK_ATOM(oncuechange, "oncuechange")
|
||||||
GK_ATOM(oncurrentchange, "oncurrentchange")
|
GK_ATOM(oncurrentchange, "oncurrentchange")
|
||||||
GK_ATOM(onenter, "onenter")
|
GK_ATOM(onenter, "onenter")
|
||||||
GK_ATOM(onexit, "onexit")
|
GK_ATOM(onexit, "onexit")
|
||||||
|
GK_ATOM(onneedkey, "onneedkey")
|
||||||
|
GK_ATOM(needkey, "needkey")
|
||||||
GK_ATOM(onremovetrack, "onremovetrack")
|
GK_ATOM(onremovetrack, "onremovetrack")
|
||||||
GK_ATOM(loadstart, "loadstart")
|
GK_ATOM(loadstart, "loadstart")
|
||||||
GK_ATOM(suspend, "suspend")
|
GK_ATOM(suspend, "suspend")
|
||||||
|
|
|
@ -235,6 +235,41 @@ nsINode::GetTextEditorRootContent(nsIEditor** aEditor)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsINode*
|
||||||
|
nsINode::SubtreeRoot() const
|
||||||
|
{
|
||||||
|
// There are four cases of interest here. nsINodes that are really:
|
||||||
|
// 1. nsIDocument nodes - Are always in the document.
|
||||||
|
// 2.a nsIContent nodes not in a shadow tree - Are either in the document,
|
||||||
|
// or mSubtreeRoot is updated in BindToTree/UnbindFromTree.
|
||||||
|
// 2.b nsIContent nodes in a shadow tree - Are never in the document,
|
||||||
|
// ignore mSubtreeRoot and return the containing shadow root.
|
||||||
|
// 4. nsIAttribute nodes - Are never in the document, and mSubtreeRoot
|
||||||
|
// is always 'this' (as set in nsINode's ctor).
|
||||||
|
nsINode* node;
|
||||||
|
if (IsInDoc()) {
|
||||||
|
node = OwnerDocAsNode();
|
||||||
|
} else if (IsContent()) {
|
||||||
|
ShadowRoot* containingShadow = AsContent()->GetContainingShadow();
|
||||||
|
node = containingShadow ? containingShadow : mSubtreeRoot;
|
||||||
|
} else {
|
||||||
|
node = mSubtreeRoot;
|
||||||
|
}
|
||||||
|
NS_ASSERTION(node, "Should always have a node here!");
|
||||||
|
#ifdef DEBUG
|
||||||
|
{
|
||||||
|
const nsINode* slowNode = this;
|
||||||
|
const nsINode* iter = slowNode;
|
||||||
|
while ((iter = iter->GetParentNode())) {
|
||||||
|
slowNode = iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_ASSERTION(slowNode == node, "These should always be in sync!");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
static nsIContent* GetRootForContentSubtree(nsIContent* aContent)
|
static nsIContent* GetRootForContentSubtree(nsIContent* aContent)
|
||||||
{
|
{
|
||||||
NS_ENSURE_TRUE(aContent, nullptr);
|
NS_ENSURE_TRUE(aContent, nullptr);
|
||||||
|
@ -268,7 +303,7 @@ nsINode::GetSelectionRootContent(nsIPresShell* aPresShell)
|
||||||
if (!IsNodeOfType(eCONTENT))
|
if (!IsNodeOfType(eCONTENT))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
if (GetCurrentDoc() != aPresShell->GetDocument()) {
|
if (GetCrossShadowCurrentDoc() != aPresShell->GetDocument()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,7 +319,7 @@ nsINode::GetSelectionRootContent(nsIPresShell* aPresShell)
|
||||||
nsIEditor* editor = nsContentUtils::GetHTMLEditor(presContext);
|
nsIEditor* editor = nsContentUtils::GetHTMLEditor(presContext);
|
||||||
if (editor) {
|
if (editor) {
|
||||||
// This node is in HTML editor.
|
// This node is in HTML editor.
|
||||||
nsIDocument* doc = GetCurrentDoc();
|
nsIDocument* doc = GetCrossShadowCurrentDoc();
|
||||||
if (!doc || doc->HasFlag(NODE_IS_EDITABLE) ||
|
if (!doc || doc->HasFlag(NODE_IS_EDITABLE) ||
|
||||||
!HasFlag(NODE_IS_EDITABLE)) {
|
!HasFlag(NODE_IS_EDITABLE)) {
|
||||||
nsIContent* editorRoot = GetEditorRootContent(editor);
|
nsIContent* editorRoot = GetEditorRootContent(editor);
|
||||||
|
@ -348,6 +383,17 @@ nsINode::GetTextContentInternal(nsAString& aTextContent)
|
||||||
SetDOMStringToNull(aTextContent);
|
SetDOMStringToNull(aTextContent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsIDocument*
|
||||||
|
nsINode::GetCrossShadowCurrentDocInternal() const
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(HasFlag(NODE_IS_IN_SHADOW_TREE) && IsContent(),
|
||||||
|
"Should only be caled on nodes in the shadow tree.");
|
||||||
|
|
||||||
|
// Cross ShadowRoot boundary.
|
||||||
|
ShadowRoot* containingShadow = AsContent()->GetContainingShadow();
|
||||||
|
return containingShadow->GetHost()->GetCrossShadowCurrentDoc();
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
void
|
void
|
||||||
nsINode::CheckNotNativeAnonymous() const
|
nsINode::CheckNotNativeAnonymous() const
|
||||||
|
@ -1461,7 +1507,7 @@ nsINode::doInsertChildAt(nsIContent* aKid, uint32_t aIndex,
|
||||||
|
|
||||||
// Do this before checking the child-count since this could cause mutations
|
// Do this before checking the child-count since this could cause mutations
|
||||||
nsIDocument* doc = GetCurrentDoc();
|
nsIDocument* doc = GetCurrentDoc();
|
||||||
mozAutoDocUpdate updateBatch(doc, UPDATE_CONTENT_MODEL, aNotify);
|
mozAutoDocUpdate updateBatch(GetCrossShadowCurrentDoc(), UPDATE_CONTENT_MODEL, aNotify);
|
||||||
|
|
||||||
if (OwnerDoc() != aKid->OwnerDoc()) {
|
if (OwnerDoc() != aKid->OwnerDoc()) {
|
||||||
rv = AdoptNodeIntoOwnerDoc(this, aKid);
|
rv = AdoptNodeIntoOwnerDoc(this, aKid);
|
||||||
|
@ -1601,10 +1647,7 @@ nsINode::doRemoveChildAt(uint32_t aIndex, bool aNotify,
|
||||||
IndexOf(aKid) == (int32_t)aIndex, "Bogus aKid");
|
IndexOf(aKid) == (int32_t)aIndex, "Bogus aKid");
|
||||||
|
|
||||||
nsMutationGuard::DidMutate();
|
nsMutationGuard::DidMutate();
|
||||||
|
mozAutoDocUpdate updateBatch(GetCrossShadowCurrentDoc(), UPDATE_CONTENT_MODEL, aNotify);
|
||||||
nsIDocument* doc = GetCurrentDoc();
|
|
||||||
|
|
||||||
mozAutoDocUpdate updateBatch(doc, UPDATE_CONTENT_MODEL, aNotify);
|
|
||||||
|
|
||||||
nsIContent* previousSibling = aKid->GetPreviousSibling();
|
nsIContent* previousSibling = aKid->GetPreviousSibling();
|
||||||
|
|
||||||
|
@ -2042,7 +2085,7 @@ nsINode::ReplaceOrInsertBefore(bool aReplace, nsINode* aNewChild,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mozAutoDocUpdate batch(GetCurrentDoc(), UPDATE_CONTENT_MODEL, true);
|
mozAutoDocUpdate batch(GetCrossShadowCurrentDoc(), UPDATE_CONTENT_MODEL, true);
|
||||||
nsAutoMutationBatch mb;
|
nsAutoMutationBatch mb;
|
||||||
|
|
||||||
// Figure out which index we want to insert at. Note that we use
|
// Figure out which index we want to insert at. Note that we use
|
||||||
|
|
|
@ -114,8 +114,8 @@ nsScriptElement::MaybeProcessScript()
|
||||||
NS_ASSERTION(cont->DebugGetSlots()->mMutationObservers.Contains(this),
|
NS_ASSERTION(cont->DebugGetSlots()->mMutationObservers.Contains(this),
|
||||||
"You forgot to add self as observer");
|
"You forgot to add self as observer");
|
||||||
|
|
||||||
if (mAlreadyStarted || !mDoneAddingChildren || !cont->IsInDoc() ||
|
if (mAlreadyStarted || !mDoneAddingChildren ||
|
||||||
mMalformed || !HasScriptContent()) {
|
!cont->GetCrossShadowCurrentDoc() || mMalformed || !HasScriptContent()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -317,11 +317,16 @@ nsStyleLinkElement::DoUpdateStyleSheet(nsIDocument* aOldDocument,
|
||||||
|
|
||||||
Element* oldScopeElement = GetScopeElement(mStyleSheet);
|
Element* oldScopeElement = GetScopeElement(mStyleSheet);
|
||||||
|
|
||||||
if (mStyleSheet && aOldDocument) {
|
if (mStyleSheet && (aOldDocument || aOldShadowRoot)) {
|
||||||
// We're removing the link element from the document, unload the
|
MOZ_ASSERT(!(aOldDocument && aOldShadowRoot),
|
||||||
// stylesheet. We want to do this even if updates are disabled, since
|
"ShadowRoot content is never in document, thus "
|
||||||
// otherwise a sheet with a stale linking element pointer will be hanging
|
"there should not be a old document and old "
|
||||||
// around -- not good!
|
"ShadowRoot simultaneously.");
|
||||||
|
|
||||||
|
// We're removing the link element from the document or shadow tree,
|
||||||
|
// unload the stylesheet. We want to do this even if updates are
|
||||||
|
// disabled, since otherwise a sheet with a stale linking element pointer
|
||||||
|
// will be hanging around -- not good!
|
||||||
if (aOldShadowRoot) {
|
if (aOldShadowRoot) {
|
||||||
aOldShadowRoot->RemoveSheet(mStyleSheet);
|
aOldShadowRoot->RemoveSheet(mStyleSheet);
|
||||||
} else {
|
} else {
|
||||||
|
@ -342,8 +347,7 @@ nsStyleLinkElement::DoUpdateStyleSheet(nsIDocument* aOldDocument,
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIDocument> doc = thisContent->GetDocument();
|
nsCOMPtr<nsIDocument> doc = thisContent->GetCrossShadowCurrentDoc();
|
||||||
|
|
||||||
if (!doc || !doc->CSSLoader()->GetEnabled()) {
|
if (!doc || !doc->CSSLoader()->GetEnabled()) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,10 +28,6 @@ function examiner() {
|
||||||
|
|
||||||
examiner.prototype = {
|
examiner.prototype = {
|
||||||
observe: function(subject, topic, data) {
|
observe: function(subject, topic, data) {
|
||||||
// subject should be an nsURI
|
|
||||||
if(!SpecialPowers.can_QI(subject))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (topic === "specialpowers-http-notify-request") {
|
if (topic === "specialpowers-http-notify-request") {
|
||||||
// this is used to fail the test - if we see the POST to the target of the redirect
|
// this is used to fail the test - if we see the POST to the target of the redirect
|
||||||
// we know this is a fail
|
// we know this is a fail
|
||||||
|
|
|
@ -28,10 +28,6 @@ function examiner() {
|
||||||
|
|
||||||
examiner.prototype = {
|
examiner.prototype = {
|
||||||
observe: function(subject, topic, data) {
|
observe: function(subject, topic, data) {
|
||||||
// subject should be an nsURI
|
|
||||||
if(!SpecialPowers.can_QI(subject))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (topic === "specialpowers-http-notify-request") {
|
if (topic === "specialpowers-http-notify-request") {
|
||||||
// this is used to fail the test - if we see the POST to the target of the redirect
|
// this is used to fail the test - if we see the POST to the target of the redirect
|
||||||
// we know this is a fail
|
// we know this is a fail
|
||||||
|
|
|
@ -28,10 +28,6 @@ function examiner() {
|
||||||
|
|
||||||
examiner.prototype = {
|
examiner.prototype = {
|
||||||
observe: function(subject, topic, data) {
|
observe: function(subject, topic, data) {
|
||||||
// subject should be an nsURI
|
|
||||||
if(!SpecialPowers.can_QI(subject))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (topic === "specialpowers-http-notify-request") {
|
if (topic === "specialpowers-http-notify-request") {
|
||||||
// this is used to fail the test - if we see the POST to the target of the redirect
|
// this is used to fail the test - if we see the POST to the target of the redirect
|
||||||
// we know this is a fail
|
// we know this is a fail
|
||||||
|
|
|
@ -28,10 +28,6 @@ function examiner() {
|
||||||
|
|
||||||
examiner.prototype = {
|
examiner.prototype = {
|
||||||
observe: function(subject, topic, data) {
|
observe: function(subject, topic, data) {
|
||||||
// subject should be an nsURI
|
|
||||||
if(!SpecialPowers.can_QI(subject))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (topic === "specialpowers-http-notify-request") {
|
if (topic === "specialpowers-http-notify-request") {
|
||||||
// this is used to fail the test - if we see the POST to the target of the redirect
|
// this is used to fail the test - if we see the POST to the target of the redirect
|
||||||
// we know this is a fail
|
// we know this is a fail
|
||||||
|
|
|
@ -20,6 +20,16 @@
|
||||||
#include "mozilla/dom/AudioChannelBinding.h"
|
#include "mozilla/dom/AudioChannelBinding.h"
|
||||||
#include "mozilla/dom/TextTrackManager.h"
|
#include "mozilla/dom/TextTrackManager.h"
|
||||||
#include "MediaDecoder.h"
|
#include "MediaDecoder.h"
|
||||||
|
#include "mozilla/dom/MediaKeys.h"
|
||||||
|
|
||||||
|
// Something on Linux #defines None, which is an entry in the
|
||||||
|
// MediaWaitingFor enum, so undef it here before including the binfing,
|
||||||
|
// so that the build doesn't fail...
|
||||||
|
#ifdef None
|
||||||
|
#undef None
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "mozilla/dom/HTMLMediaElementBinding.h"
|
||||||
|
|
||||||
// Define to output information on decoding and painting framerate
|
// Define to output information on decoding and painting framerate
|
||||||
/* #define DEBUG_FRAME_RATE 1 */
|
/* #define DEBUG_FRAME_RATE 1 */
|
||||||
|
@ -37,6 +47,7 @@ class MediaResource;
|
||||||
class MediaDecoder;
|
class MediaDecoder;
|
||||||
class VideoFrameContainer;
|
class VideoFrameContainer;
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
class MediaKeys;
|
||||||
class TextTrack;
|
class TextTrack;
|
||||||
class TimeRanges;
|
class TimeRanges;
|
||||||
class WakeLock;
|
class WakeLock;
|
||||||
|
@ -467,6 +478,16 @@ public:
|
||||||
SetHTMLBoolAttr(nsGkAtoms::muted, aMuted, aRv);
|
SetHTMLBoolAttr(nsGkAtoms::muted, aMuted, aRv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MozMediaStatisticsShowing() const
|
||||||
|
{
|
||||||
|
return mStatsShowing;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetMozMediaStatisticsShowing(bool aShow)
|
||||||
|
{
|
||||||
|
mStatsShowing = aShow;
|
||||||
|
}
|
||||||
|
|
||||||
already_AddRefed<DOMMediaStream> GetMozSrcObject() const;
|
already_AddRefed<DOMMediaStream> GetMozSrcObject() const;
|
||||||
|
|
||||||
void SetMozSrcObject(DOMMediaStream& aValue);
|
void SetMozSrcObject(DOMMediaStream& aValue);
|
||||||
|
@ -478,6 +499,22 @@ public:
|
||||||
|
|
||||||
// XPCOM MozPreservesPitch() is OK
|
// XPCOM MozPreservesPitch() is OK
|
||||||
|
|
||||||
|
MediaKeys* GetMediaKeys() const;
|
||||||
|
|
||||||
|
already_AddRefed<Promise> SetMediaKeys(MediaKeys* mediaKeys,
|
||||||
|
ErrorResult& aRv);
|
||||||
|
|
||||||
|
MediaWaitingFor WaitingFor() const;
|
||||||
|
|
||||||
|
mozilla::dom::EventHandlerNonNull* GetOnneedkey();
|
||||||
|
void SetOnneedkey(mozilla::dom::EventHandlerNonNull* listener);
|
||||||
|
|
||||||
|
void DispatchNeedKey(const nsTArray<uint8_t>& aInitData,
|
||||||
|
const nsAString& aInitDataType);
|
||||||
|
|
||||||
|
|
||||||
|
bool IsEventAttributeName(nsIAtom* aName) MOZ_OVERRIDE;
|
||||||
|
|
||||||
bool MozAutoplayEnabled() const
|
bool MozAutoplayEnabled() const
|
||||||
{
|
{
|
||||||
return mAutoplayEnabled;
|
return mAutoplayEnabled;
|
||||||
|
@ -1010,6 +1047,9 @@ protected:
|
||||||
// Range of time played.
|
// Range of time played.
|
||||||
nsRefPtr<TimeRanges> mPlayed;
|
nsRefPtr<TimeRanges> mPlayed;
|
||||||
|
|
||||||
|
// Encrypted Media Extension media keys.
|
||||||
|
nsRefPtr<MediaKeys> mMediaKeys;
|
||||||
|
|
||||||
// Stores the time at the start of the current 'played' range.
|
// Stores the time at the start of the current 'played' range.
|
||||||
double mCurrentPlayRangeStart;
|
double mCurrentPlayRangeStart;
|
||||||
|
|
||||||
|
@ -1048,6 +1088,10 @@ protected:
|
||||||
|
|
||||||
uint32_t mMuted;
|
uint32_t mMuted;
|
||||||
|
|
||||||
|
// True if the media statistics are currently being shown by the builtin
|
||||||
|
// video controls
|
||||||
|
bool mStatsShowing;
|
||||||
|
|
||||||
// True if the sound is being captured.
|
// True if the sound is being captured.
|
||||||
bool mAudioCaptured;
|
bool mAudioCaptured;
|
||||||
|
|
||||||
|
@ -1139,6 +1183,8 @@ protected:
|
||||||
nsCOMPtr<nsIAudioChannelAgent> mAudioChannelAgent;
|
nsCOMPtr<nsIAudioChannelAgent> mAudioChannelAgent;
|
||||||
|
|
||||||
nsRefPtr<TextTrackManager> mTextTrackManager;
|
nsRefPtr<TextTrackManager> mTextTrackManager;
|
||||||
|
|
||||||
|
MediaWaitingFor mWaitingFor;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "mozilla/EventDispatcher.h"
|
#include "mozilla/EventDispatcher.h"
|
||||||
#include "mozilla/EventStateManager.h"
|
#include "mozilla/EventStateManager.h"
|
||||||
#include "mozilla/EventStates.h"
|
#include "mozilla/EventStates.h"
|
||||||
|
#include "mozilla/dom/AutocompleteErrorEvent.h"
|
||||||
#include "mozilla/dom/HTMLFormControlsCollection.h"
|
#include "mozilla/dom/HTMLFormControlsCollection.h"
|
||||||
#include "mozilla/dom/HTMLFormElementBinding.h"
|
#include "mozilla/dom/HTMLFormElementBinding.h"
|
||||||
#include "mozilla/Move.h"
|
#include "mozilla/Move.h"
|
||||||
|
@ -28,6 +29,7 @@
|
||||||
#include "nsAutoPtr.h"
|
#include "nsAutoPtr.h"
|
||||||
#include "nsTArray.h"
|
#include "nsTArray.h"
|
||||||
#include "nsIMutableArray.h"
|
#include "nsIMutableArray.h"
|
||||||
|
#include "nsIAutofillController.h"
|
||||||
|
|
||||||
// form submission
|
// form submission
|
||||||
#include "nsIFormSubmitObserver.h"
|
#include "nsIFormSubmitObserver.h"
|
||||||
|
@ -300,6 +302,28 @@ HTMLFormElement::CheckValidity(bool* retVal)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HTMLFormElement::RequestAutocomplete()
|
||||||
|
{
|
||||||
|
bool dummy;
|
||||||
|
nsCOMPtr<nsIDOMWindow> win = do_QueryInterface(OwnerDoc()->GetScriptHandlingObject(dummy));
|
||||||
|
nsCOMPtr<nsIAutofillController> controller(do_GetService("@mozilla.org/autofill-controller;1"));
|
||||||
|
|
||||||
|
if (!controller || !win) {
|
||||||
|
AutocompleteErrorEventInit init;
|
||||||
|
init.mBubbles = true;
|
||||||
|
init.mCancelable = false;
|
||||||
|
init.mReason = AutoCompleteErrorReason::Disabled;
|
||||||
|
|
||||||
|
nsRefPtr<AutocompleteErrorEvent> event =
|
||||||
|
AutocompleteErrorEvent::Constructor(this, NS_LITERAL_STRING("autocompleteerror"), init);
|
||||||
|
(new AsyncEventDispatcher(this, event))->PostDOMEvent();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
controller->RequestAutocomplete(this, win);
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
HTMLFormElement::ParseAttribute(int32_t aNamespaceID,
|
HTMLFormElement::ParseAttribute(int32_t aNamespaceID,
|
||||||
nsIAtom* aAttribute,
|
nsIAtom* aAttribute,
|
||||||
|
|
|
@ -410,6 +410,8 @@ public:
|
||||||
|
|
||||||
js::ExpandoAndGeneration mExpandoAndGeneration;
|
js::ExpandoAndGeneration mExpandoAndGeneration;
|
||||||
|
|
||||||
|
void RequestAutocomplete();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual JSObject* WrapNode(JSContext* aCx) MOZ_OVERRIDE;
|
virtual JSObject* WrapNode(JSContext* aCx) MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
|
|
@ -190,13 +190,13 @@ static const nsAttrValue::EnumTable kInputInputmodeTable[] = {
|
||||||
// Default inputmode value is "auto".
|
// Default inputmode value is "auto".
|
||||||
static const nsAttrValue::EnumTable* kInputDefaultInputmode = &kInputInputmodeTable[0];
|
static const nsAttrValue::EnumTable* kInputDefaultInputmode = &kInputInputmodeTable[0];
|
||||||
|
|
||||||
const Decimal HTMLInputElement::kStepScaleFactorDate = 86400000;
|
const Decimal HTMLInputElement::kStepScaleFactorDate = Decimal(86400000);
|
||||||
const Decimal HTMLInputElement::kStepScaleFactorNumberRange = 1;
|
const Decimal HTMLInputElement::kStepScaleFactorNumberRange = Decimal(1);
|
||||||
const Decimal HTMLInputElement::kStepScaleFactorTime = 1000;
|
const Decimal HTMLInputElement::kStepScaleFactorTime = Decimal(1000);
|
||||||
const Decimal HTMLInputElement::kDefaultStepBase = 0;
|
const Decimal HTMLInputElement::kDefaultStepBase = Decimal(0);
|
||||||
const Decimal HTMLInputElement::kDefaultStep = 1;
|
const Decimal HTMLInputElement::kDefaultStep = Decimal(1);
|
||||||
const Decimal HTMLInputElement::kDefaultStepTime = 60;
|
const Decimal HTMLInputElement::kDefaultStepTime = Decimal(60);
|
||||||
const Decimal HTMLInputElement::kStepAny = 0;
|
const Decimal HTMLInputElement::kStepAny = Decimal(0);
|
||||||
|
|
||||||
#define NS_INPUT_ELEMENT_STATE_IID \
|
#define NS_INPUT_ELEMENT_STATE_IID \
|
||||||
{ /* dc3b3d14-23e2-4479-b513-7b369343e3a0 */ \
|
{ /* dc3b3d14-23e2-4479-b513-7b369343e3a0 */ \
|
||||||
|
@ -1754,7 +1754,7 @@ HTMLInputElement::ConvertStringToNumber(nsAString& aValue,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
aResultValue = int32_t(milliseconds);
|
aResultValue = Decimal(int32_t(milliseconds));
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
MOZ_ASSERT(false, "Unrecognized input type");
|
MOZ_ASSERT(false, "Unrecognized input type");
|
||||||
|
@ -1929,7 +1929,7 @@ HTMLInputElement::ConvertNumberToString(Decimal aValue,
|
||||||
// Per spec, we need to truncate |aValue| and we should only represent
|
// Per spec, we need to truncate |aValue| and we should only represent
|
||||||
// times inside a day [00:00, 24:00[, which means that we should do a
|
// times inside a day [00:00, 24:00[, which means that we should do a
|
||||||
// modulo on |aValue| using the number of milliseconds in a day (86400000).
|
// modulo on |aValue| using the number of milliseconds in a day (86400000).
|
||||||
uint32_t value = NS_floorModulo(aValue.floor(), 86400000).toDouble();
|
uint32_t value = NS_floorModulo(aValue.floor(), Decimal(86400000)).toDouble();
|
||||||
|
|
||||||
uint16_t milliseconds = value % 1000;
|
uint16_t milliseconds = value % 1000;
|
||||||
value /= 1000;
|
value /= 1000;
|
||||||
|
@ -2055,7 +2055,7 @@ HTMLInputElement::GetMinimum() const
|
||||||
|
|
||||||
// Only type=range has a default minimum
|
// Only type=range has a default minimum
|
||||||
Decimal defaultMinimum =
|
Decimal defaultMinimum =
|
||||||
mType == NS_FORM_INPUT_RANGE ? 0 : Decimal::nan();
|
mType == NS_FORM_INPUT_RANGE ? Decimal(0) : Decimal::nan();
|
||||||
|
|
||||||
if (!HasAttr(kNameSpaceID_None, nsGkAtoms::min)) {
|
if (!HasAttr(kNameSpaceID_None, nsGkAtoms::min)) {
|
||||||
return defaultMinimum;
|
return defaultMinimum;
|
||||||
|
@ -2076,7 +2076,7 @@ HTMLInputElement::GetMaximum() const
|
||||||
|
|
||||||
// Only type=range has a default maximum
|
// Only type=range has a default maximum
|
||||||
Decimal defaultMaximum =
|
Decimal defaultMaximum =
|
||||||
mType == NS_FORM_INPUT_RANGE ? 100 : Decimal::nan();
|
mType == NS_FORM_INPUT_RANGE ? Decimal(100) : Decimal::nan();
|
||||||
|
|
||||||
if (!HasAttr(kNameSpaceID_None, nsGkAtoms::max)) {
|
if (!HasAttr(kNameSpaceID_None, nsGkAtoms::max)) {
|
||||||
return defaultMaximum;
|
return defaultMaximum;
|
||||||
|
@ -2138,7 +2138,7 @@ HTMLInputElement::GetValueIfStepped(int32_t aStep,
|
||||||
|
|
||||||
Decimal value = GetValueAsDecimal();
|
Decimal value = GetValueAsDecimal();
|
||||||
if (value.isNaN()) {
|
if (value.isNaN()) {
|
||||||
value = 0;
|
value = Decimal(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Decimal minimum = GetMinimum();
|
Decimal minimum = GetMinimum();
|
||||||
|
@ -2176,14 +2176,14 @@ HTMLInputElement::GetValueIfStepped(int32_t aStep,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
value += step * aStep;
|
value += step * Decimal(aStep);
|
||||||
|
|
||||||
// For date inputs, the value can hold a string that is not a day. We do not
|
// For date inputs, the value can hold a string that is not a day. We do not
|
||||||
// want to round it, as it might result in a step mismatch. Instead we want to
|
// want to round it, as it might result in a step mismatch. Instead we want to
|
||||||
// clamp to the next valid value.
|
// clamp to the next valid value.
|
||||||
if (mType == NS_FORM_INPUT_DATE &&
|
if (mType == NS_FORM_INPUT_DATE &&
|
||||||
NS_floorModulo(value - GetStepBase(), GetStepScaleFactor()) != 0) {
|
NS_floorModulo(Decimal(value - GetStepBase()), GetStepScaleFactor()) != Decimal(0)) {
|
||||||
MOZ_ASSERT(GetStep() > 0);
|
MOZ_ASSERT(GetStep() > Decimal(0));
|
||||||
Decimal validStep = EuclidLCM<Decimal>(GetStep().floor(),
|
Decimal validStep = EuclidLCM<Decimal>(GetStep().floor(),
|
||||||
GetStepScaleFactor().floor());
|
GetStepScaleFactor().floor());
|
||||||
if (aStep > 0) {
|
if (aStep > 0) {
|
||||||
|
@ -4116,10 +4116,10 @@ HTMLInputElement::PostHandleEvent(EventChainPostVisitor& aVisitor)
|
||||||
case NS_VK_PAGE_UP:
|
case NS_VK_PAGE_UP:
|
||||||
// For PgUp/PgDn we jump 10% of the total range, unless step
|
// For PgUp/PgDn we jump 10% of the total range, unless step
|
||||||
// requires us to jump more.
|
// requires us to jump more.
|
||||||
newValue = value + std::max(step, (maximum - minimum) / 10);
|
newValue = value + std::max(step, (maximum - minimum) / Decimal(10));
|
||||||
break;
|
break;
|
||||||
case NS_VK_PAGE_DOWN:
|
case NS_VK_PAGE_DOWN:
|
||||||
newValue = value - std::max(step, (maximum - minimum) / 10);
|
newValue = value - std::max(step, (maximum - minimum) / Decimal(10));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
SetValueOfRangeForUserEvent(newValue);
|
SetValueOfRangeForUserEvent(newValue);
|
||||||
|
@ -4567,7 +4567,7 @@ HTMLInputElement::SanitizeValue(nsAString& aValue)
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
needSanitization = true;
|
needSanitization = true;
|
||||||
// Set value to midway between minimum and maximum.
|
// Set value to midway between minimum and maximum.
|
||||||
value = maximum <= minimum ? minimum : minimum + (maximum - minimum)/2;
|
value = maximum <= minimum ? minimum : minimum + (maximum - minimum)/Decimal(2);
|
||||||
} else if (value < minimum || maximum < minimum) {
|
} else if (value < minimum || maximum < minimum) {
|
||||||
needSanitization = true;
|
needSanitization = true;
|
||||||
value = minimum;
|
value = minimum;
|
||||||
|
@ -4583,17 +4583,17 @@ HTMLInputElement::SanitizeValue(nsAString& aValue)
|
||||||
// numbers, but let's ignore that until ECMAScript supplies us with a
|
// numbers, but let's ignore that until ECMAScript supplies us with a
|
||||||
// decimal number type.
|
// decimal number type.
|
||||||
Decimal deltaToStep = NS_floorModulo(value - stepBase, step);
|
Decimal deltaToStep = NS_floorModulo(value - stepBase, step);
|
||||||
if (deltaToStep != 0) {
|
if (deltaToStep != Decimal(0)) {
|
||||||
// "suffering from a step mismatch"
|
// "suffering from a step mismatch"
|
||||||
// Round the element's value to the nearest number for which the
|
// Round the element's value to the nearest number for which the
|
||||||
// element would not suffer from a step mismatch, and which is
|
// element would not suffer from a step mismatch, and which is
|
||||||
// greater than or equal to the minimum, and, if the maximum is not
|
// greater than or equal to the minimum, and, if the maximum is not
|
||||||
// less than the minimum, which is less than or equal to the
|
// less than the minimum, which is less than or equal to the
|
||||||
// maximum, if there is a number that matches these constraints:
|
// maximum, if there is a number that matches these constraints:
|
||||||
MOZ_ASSERT(deltaToStep > 0, "stepBelow/stepAbove will be wrong");
|
MOZ_ASSERT(deltaToStep > Decimal(0), "stepBelow/stepAbove will be wrong");
|
||||||
Decimal stepBelow = value - deltaToStep;
|
Decimal stepBelow = value - deltaToStep;
|
||||||
Decimal stepAbove = value - deltaToStep + step;
|
Decimal stepAbove = value - deltaToStep + step;
|
||||||
Decimal halfStep = step / 2;
|
Decimal halfStep = step / Decimal(2);
|
||||||
bool stepAboveIsClosest = (stepAbove - value) <= halfStep;
|
bool stepAboveIsClosest = (stepAbove - value) <= halfStep;
|
||||||
bool stepAboveInRange = stepAbove >= minimum &&
|
bool stepAboveInRange = stepAbove >= minimum &&
|
||||||
stepAbove <= maximum;
|
stepAbove <= maximum;
|
||||||
|
@ -6276,7 +6276,7 @@ HTMLInputElement::GetStep() const
|
||||||
}
|
}
|
||||||
|
|
||||||
Decimal step = StringToDecimal(stepStr);
|
Decimal step = StringToDecimal(stepStr);
|
||||||
if (!step.isFinite() || step <= 0) {
|
if (!step.isFinite() || step <= Decimal(0)) {
|
||||||
step = GetDefaultStep();
|
step = GetDefaultStep();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6462,7 +6462,7 @@ HTMLInputElement::HasStepMismatch(bool aUseZeroIfValueNaN) const
|
||||||
Decimal value = GetValueAsDecimal();
|
Decimal value = GetValueAsDecimal();
|
||||||
if (value.isNaN()) {
|
if (value.isNaN()) {
|
||||||
if (aUseZeroIfValueNaN) {
|
if (aUseZeroIfValueNaN) {
|
||||||
value = 0;
|
value = Decimal(0);
|
||||||
} else {
|
} else {
|
||||||
// The element can't suffer from step mismatch if it's value isn't a number.
|
// The element can't suffer from step mismatch if it's value isn't a number.
|
||||||
return false;
|
return false;
|
||||||
|
@ -6475,7 +6475,7 @@ HTMLInputElement::HasStepMismatch(bool aUseZeroIfValueNaN) const
|
||||||
}
|
}
|
||||||
|
|
||||||
// Value has to be an integral multiple of step.
|
// Value has to be an integral multiple of step.
|
||||||
return NS_floorModulo(value - GetStepBase(), step) != 0;
|
return NS_floorModulo(value - GetStepBase(), step) != Decimal(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -6881,7 +6881,7 @@ HTMLInputElement::GetValidationMessage(nsAString& aValidationMessage,
|
||||||
MOZ_ASSERT(!value.isNaN());
|
MOZ_ASSERT(!value.isNaN());
|
||||||
|
|
||||||
Decimal step = GetStep();
|
Decimal step = GetStep();
|
||||||
MOZ_ASSERT(step != kStepAny && step > 0);
|
MOZ_ASSERT(step != kStepAny && step > Decimal(0));
|
||||||
|
|
||||||
// In case this is a date and the step is not an integer, we don't want to
|
// In case this is a date and the step is not an integer, we don't want to
|
||||||
// display the dates corresponding to the truncated timestamps of valueLow
|
// display the dates corresponding to the truncated timestamps of valueLow
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
#include "mozilla/dom/ElementInlines.h"
|
#include "mozilla/dom/ElementInlines.h"
|
||||||
#include "mozilla/ArrayUtils.h"
|
#include "mozilla/ArrayUtils.h"
|
||||||
#include "mozilla/MathAlgorithms.h"
|
#include "mozilla/MathAlgorithms.h"
|
||||||
|
#include "mozilla/dom/MediaKeyNeededEvent.h"
|
||||||
|
#include "mozilla/AsyncEventDispatcher.h"
|
||||||
|
|
||||||
#include "base/basictypes.h"
|
#include "base/basictypes.h"
|
||||||
#include "nsIDOMHTMLMediaElement.h"
|
#include "nsIDOMHTMLMediaElement.h"
|
||||||
|
@ -423,6 +425,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLMediaElement, nsGenericHTM
|
||||||
}
|
}
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPlayed);
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPlayed);
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTextTrackManager)
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTextTrackManager)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMediaKeys)
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLMediaElement, nsGenericHTMLElement)
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLMediaElement, nsGenericHTMLElement)
|
||||||
|
@ -439,10 +442,11 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLMediaElement, nsGenericHTMLE
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mAudioChannelAgent)
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mAudioChannelAgent)
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mError)
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mError)
|
||||||
for (uint32_t i = 0; i < tmp->mOutputStreams.Length(); ++i) {
|
for (uint32_t i = 0; i < tmp->mOutputStreams.Length(); ++i) {
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mOutputStreams[i].mStream);
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mOutputStreams[i].mStream)
|
||||||
}
|
}
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mPlayed);
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mPlayed)
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mTextTrackManager)
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mTextTrackManager)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mMediaKeys)
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||||
|
|
||||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(HTMLMediaElement)
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(HTMLMediaElement)
|
||||||
|
@ -895,6 +899,9 @@ void HTMLMediaElement::LoadFromSourceChildren()
|
||||||
ReportLoadError("MediaLoadUnsupportedTypeAttribute", params, ArrayLength(params));
|
ReportLoadError("MediaLoadUnsupportedTypeAttribute", params, ArrayLength(params));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
// TODO: "If candidate has a keySystem attribute whose value represents a
|
||||||
|
// Key System that the user agent knows it cannot use with type,
|
||||||
|
// then end the synchronous section[...]" (Bug 1016707)
|
||||||
nsAutoString media;
|
nsAutoString media;
|
||||||
if (child->GetAttr(kNameSpaceID_None, nsGkAtoms::media, media) && !media.IsEmpty()) {
|
if (child->GetAttr(kNameSpaceID_None, nsGkAtoms::media, media) && !media.IsEmpty()) {
|
||||||
nsCSSParser cssParser;
|
nsCSSParser cssParser;
|
||||||
|
@ -1982,6 +1989,7 @@ HTMLMediaElement::HTMLMediaElement(already_AddRefed<nsINodeInfo>& aNodeInfo)
|
||||||
mAutoplayEnabled(true),
|
mAutoplayEnabled(true),
|
||||||
mPaused(true),
|
mPaused(true),
|
||||||
mMuted(0),
|
mMuted(0),
|
||||||
|
mStatsShowing(false),
|
||||||
mAudioCaptured(false),
|
mAudioCaptured(false),
|
||||||
mPlayingBeforeSeek(false),
|
mPlayingBeforeSeek(false),
|
||||||
mPausedForInactiveDocumentOrChannel(false),
|
mPausedForInactiveDocumentOrChannel(false),
|
||||||
|
@ -2003,7 +2011,8 @@ HTMLMediaElement::HTMLMediaElement(already_AddRefed<nsINodeInfo>& aNodeInfo)
|
||||||
mHasAudio(false),
|
mHasAudio(false),
|
||||||
mDownloadSuspendedByCache(false),
|
mDownloadSuspendedByCache(false),
|
||||||
mAudioChannelFaded(false),
|
mAudioChannelFaded(false),
|
||||||
mPlayingThroughTheAudioChannel(false)
|
mPlayingThroughTheAudioChannel(false),
|
||||||
|
mWaitingFor(MediaWaitingFor::None)
|
||||||
{
|
{
|
||||||
#ifdef PR_LOGGING
|
#ifdef PR_LOGGING
|
||||||
if (!gMediaElementLog) {
|
if (!gMediaElementLog) {
|
||||||
|
@ -3894,6 +3903,72 @@ NS_IMETHODIMP HTMLMediaElement::CanPlayChanged(int32_t canPlay)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MediaKeys*
|
||||||
|
HTMLMediaElement::GetMediaKeys() const
|
||||||
|
{
|
||||||
|
return mMediaKeys;
|
||||||
|
}
|
||||||
|
|
||||||
|
already_AddRefed<Promise>
|
||||||
|
HTMLMediaElement::SetMediaKeys(mozilla::dom::MediaKeys* aMediaKeys,
|
||||||
|
ErrorResult& aRv)
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIGlobalObject> global =
|
||||||
|
do_QueryInterface(OwnerDoc()->GetInnerWindow());
|
||||||
|
if (!global) {
|
||||||
|
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
// TODO: Need to shutdown existing MediaKeys instance? bug 1016709.
|
||||||
|
nsRefPtr<Promise> promise = new Promise(global);
|
||||||
|
if (mMediaKeys != aMediaKeys) {
|
||||||
|
mMediaKeys = aMediaKeys;
|
||||||
|
}
|
||||||
|
promise->MaybeResolve(JS::UndefinedHandleValue);
|
||||||
|
return promise.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
MediaWaitingFor
|
||||||
|
HTMLMediaElement::WaitingFor() const
|
||||||
|
{
|
||||||
|
return mWaitingFor;
|
||||||
|
}
|
||||||
|
|
||||||
|
EventHandlerNonNull*
|
||||||
|
HTMLMediaElement::GetOnneedkey()
|
||||||
|
{
|
||||||
|
EventListenerManager *elm = GetExistingListenerManager();
|
||||||
|
return elm ? elm->GetEventHandler(nsGkAtoms::onneedkey, EmptyString())
|
||||||
|
: nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HTMLMediaElement::SetOnneedkey(EventHandlerNonNull* handler)
|
||||||
|
{
|
||||||
|
EventListenerManager *elm = GetOrCreateListenerManager();
|
||||||
|
if (elm) {
|
||||||
|
elm->SetEventHandler(nsGkAtoms::onneedkey, EmptyString(), handler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HTMLMediaElement::DispatchNeedKey(const nsTArray<uint8_t>& aInitData,
|
||||||
|
const nsAString& aInitDataType)
|
||||||
|
{
|
||||||
|
nsRefPtr<MediaKeyNeededEvent> event(
|
||||||
|
MediaKeyNeededEvent::Constructor(this, aInitDataType, aInitData));
|
||||||
|
nsRefPtr<AsyncEventDispatcher> asyncDispatcher =
|
||||||
|
new AsyncEventDispatcher(this, event);
|
||||||
|
asyncDispatcher->PostDOMEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
HTMLMediaElement::IsEventAttributeName(nsIAtom* aName)
|
||||||
|
{
|
||||||
|
return aName == nsGkAtoms::onneedkey ||
|
||||||
|
nsGenericHTMLElement::IsEventAttributeName(aName);
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP HTMLMediaElement::WindowVolumeChanged()
|
NS_IMETHODIMP HTMLMediaElement::WindowVolumeChanged()
|
||||||
{
|
{
|
||||||
SetVolumeInternal();
|
SetVolumeInternal();
|
||||||
|
|
|
@ -62,7 +62,7 @@ HTMLScriptElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||||
aCompileEventHandlers);
|
aCompileEventHandlers);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
if (aDocument) {
|
if (GetCrossShadowCurrentDoc()) {
|
||||||
MaybeProcessScript();
|
MaybeProcessScript();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,6 +64,16 @@ public:
|
||||||
SetHTMLAttr(nsGkAtoms::media, aMedia, rv);
|
SetHTMLAttr(nsGkAtoms::media, aMedia, rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GetKeySystem(nsString& aKeySystem) const
|
||||||
|
{
|
||||||
|
GetHTMLAttr(nsGkAtoms::keysystem, aKeySystem);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetKeySystem(const nsAString& aKeySystem)
|
||||||
|
{
|
||||||
|
SetHTMLAttr(nsGkAtoms::keysystem, aKeySystem);
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual JSObject* WrapNode(JSContext* aCx) MOZ_OVERRIDE;
|
virtual JSObject* WrapNode(JSContext* aCx) MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,199 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#include "mozilla/CDMProxy.h"
|
||||||
|
#include "nsString.h"
|
||||||
|
#include "mozilla/dom/MediaKeys.h"
|
||||||
|
#include "mozilla/dom/MediaKeySession.h"
|
||||||
|
#include "mozIGeckoMediaPluginService.h"
|
||||||
|
#include "nsContentCID.h"
|
||||||
|
#include "nsServiceManagerUtils.h"
|
||||||
|
#include "MainThreadUtils.h"
|
||||||
|
|
||||||
|
// TODO: Change the functions in this file to do IPC via the Gecko Media
|
||||||
|
// Plugins API. In the meantime, the code here merely implements the
|
||||||
|
// interface we expect will be required when the IPC is working.
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
|
||||||
|
CDMProxy::CDMProxy(dom::MediaKeys* aKeys, const nsAString& aKeySystem)
|
||||||
|
: mKeys(aKeys)
|
||||||
|
, mKeySystem(aKeySystem)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
MOZ_COUNT_CTOR(CDMProxy);
|
||||||
|
}
|
||||||
|
|
||||||
|
CDMProxy::~CDMProxy()
|
||||||
|
{
|
||||||
|
MOZ_COUNT_DTOR(CDMProxy);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CDMProxy::Init(PromiseId aPromiseId)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
if (!mGMPThread) {
|
||||||
|
nsCOMPtr<mozIGeckoMediaPluginService> mps =
|
||||||
|
do_GetService("@mozilla.org/gecko-media-plugin-service;1");
|
||||||
|
if (!mps) {
|
||||||
|
RejectPromise(aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mps->GetThread(getter_AddRefs(mGMPThread));
|
||||||
|
if (!mGMPThread) {
|
||||||
|
RejectPromise(aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Dispatch task to GMPThread to initialize CDM via IPC.
|
||||||
|
|
||||||
|
mKeys->OnCDMCreated(aPromiseId);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sFakeSessionIdNum = 0;
|
||||||
|
|
||||||
|
void
|
||||||
|
CDMProxy::CreateSession(dom::SessionType aSessionType,
|
||||||
|
PromiseId aPromiseId,
|
||||||
|
const nsAString& aInitDataType,
|
||||||
|
const Uint8Array& aInitData)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
MOZ_ASSERT(mGMPThread);
|
||||||
|
|
||||||
|
// TODO: Dispatch task to GMPThread to call CDM CreateSession via IPC.
|
||||||
|
|
||||||
|
// Make a fake session id. We'll get this from the CDM normally.
|
||||||
|
nsAutoString id;
|
||||||
|
id.AppendASCII("FakeSessionId_");
|
||||||
|
id.AppendInt(sFakeSessionIdNum++);
|
||||||
|
|
||||||
|
mKeys->OnSessionActivated(aPromiseId, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CDMProxy::LoadSession(PromiseId aPromiseId,
|
||||||
|
const nsAString& aSessionId)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
MOZ_ASSERT(mGMPThread);
|
||||||
|
|
||||||
|
// TODO: Dispatch task to GMPThread to call CDM LoadSession via IPC.
|
||||||
|
// make MediaKeys::mPendingSessions CC'd
|
||||||
|
|
||||||
|
mKeys->OnSessionActivated(aPromiseId, aSessionId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CDMProxy::SetServerCertificate(PromiseId aPromiseId,
|
||||||
|
const Uint8Array& aCertData)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
MOZ_ASSERT(mGMPThread);
|
||||||
|
|
||||||
|
// TODO: Dispatch task to GMPThread to call CDM SetServerCertificate via IPC.
|
||||||
|
|
||||||
|
ResolvePromise(aPromiseId);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sUpdateCount = 0;
|
||||||
|
|
||||||
|
void
|
||||||
|
CDMProxy::UpdateSession(const nsAString& aSessionId,
|
||||||
|
PromiseId aPromiseId,
|
||||||
|
const Uint8Array& aResponse)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
MOZ_ASSERT(mGMPThread);
|
||||||
|
NS_ENSURE_TRUE_VOID(!mKeys.IsNull());
|
||||||
|
|
||||||
|
// TODO: Dispatch task to GMPThread to call CDM UpdateSession via IPC.
|
||||||
|
|
||||||
|
nsRefPtr<dom::MediaKeySession> session(mKeys->GetSession(aSessionId));
|
||||||
|
nsAutoCString str(NS_LITERAL_CSTRING("Update_"));
|
||||||
|
str.AppendInt(sUpdateCount++);
|
||||||
|
nsTArray<uint8_t> msg;
|
||||||
|
msg.AppendElements(str.get(), str.Length());
|
||||||
|
session->DispatchKeyMessage(msg, NS_LITERAL_STRING("http://bogus.url"));
|
||||||
|
ResolvePromise(aPromiseId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CDMProxy::CloseSession(const nsAString& aSessionId,
|
||||||
|
PromiseId aPromiseId)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
NS_ENSURE_TRUE_VOID(!mKeys.IsNull());
|
||||||
|
|
||||||
|
// TODO: Dispatch task to GMPThread to call CDM CloseSession via IPC.
|
||||||
|
|
||||||
|
nsRefPtr<dom::MediaKeySession> session(mKeys->GetSession(aSessionId));
|
||||||
|
|
||||||
|
// Pretend that the CDM actually does close the session...
|
||||||
|
// "...the [MediaKeySession's] closed attribute promise is resolved
|
||||||
|
// when the session is closed."
|
||||||
|
session->OnClosed();
|
||||||
|
|
||||||
|
// "The promise is resolved when the request has been processed."
|
||||||
|
ResolvePromise(aPromiseId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CDMProxy::RemoveSession(const nsAString& aSessionId,
|
||||||
|
PromiseId aPromiseId)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
|
// TODO: Dispatch task to GMPThread to call CDM RemoveSession via IPC.
|
||||||
|
|
||||||
|
// Assume CDM immediately removes session's data, then close the session
|
||||||
|
// as per the spec.
|
||||||
|
CloseSession(aSessionId, aPromiseId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CDMProxy::Shutdown()
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
mKeys.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CDMProxy::RejectPromise(PromiseId aId, nsresult aCode)
|
||||||
|
{
|
||||||
|
if (NS_IsMainThread()) {
|
||||||
|
if (!mKeys.IsNull()) {
|
||||||
|
mKeys->RejectPromise(aId, aCode);
|
||||||
|
} else {
|
||||||
|
NS_WARNING("CDMProxy unable to reject promise!");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
nsRefPtr<nsIRunnable> task(new RejectPromiseTask(this, aId, aCode));
|
||||||
|
NS_DispatchToMainThread(task);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CDMProxy::ResolvePromise(PromiseId aId)
|
||||||
|
{
|
||||||
|
if (NS_IsMainThread()) {
|
||||||
|
if (!mKeys.IsNull()) {
|
||||||
|
mKeys->ResolvePromise(aId);
|
||||||
|
} else {
|
||||||
|
NS_WARNING("CDMProxy unable to resolve promise!");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
nsRefPtr<nsIRunnable> task;
|
||||||
|
task = NS_NewRunnableMethodWithArg<PromiseId>(this,
|
||||||
|
&CDMProxy::ResolvePromise,
|
||||||
|
aId);
|
||||||
|
NS_DispatchToMainThread(task);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace mozilla
|
|
@ -0,0 +1,171 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#ifndef CDMProxy_h_
|
||||||
|
#define CDMProxy_h_
|
||||||
|
|
||||||
|
#include "nsString.h"
|
||||||
|
#include "nsAutoPtr.h"
|
||||||
|
#include "nsProxyRelease.h"
|
||||||
|
#include "mozilla/dom/MediaKeys.h"
|
||||||
|
#include "mozilla/dom/TypedArray.h"
|
||||||
|
|
||||||
|
class nsIThread;
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
|
||||||
|
namespace dom {
|
||||||
|
class MediaKeySession;
|
||||||
|
}
|
||||||
|
|
||||||
|
// A placeholder proxy to the CDM.
|
||||||
|
// TODO: The functions here need to do IPC to talk to the CDM via the
|
||||||
|
// Gecko Media Plugin API, which we'll need to extend for H.264 and EME
|
||||||
|
// content.
|
||||||
|
// Note: Promises are passed in via a PromiseId, so that the ID can be
|
||||||
|
// passed via IPC to the CDM, which can then signal when to reject or
|
||||||
|
// resolve the promise using its PromiseId.
|
||||||
|
class CDMProxy {
|
||||||
|
typedef dom::PromiseId PromiseId;
|
||||||
|
typedef dom::SessionType SessionType;
|
||||||
|
typedef dom::Uint8Array Uint8Array;
|
||||||
|
public:
|
||||||
|
|
||||||
|
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CDMProxy)
|
||||||
|
|
||||||
|
// Main thread only.
|
||||||
|
CDMProxy(dom::MediaKeys* aKeys, const nsAString& aKeySystem);
|
||||||
|
|
||||||
|
// Main thread only.
|
||||||
|
// Loads the CDM corresponding to mKeySystem.
|
||||||
|
// Calls MediaKeys::OnCDMCreated() when the CDM is created.
|
||||||
|
void Init(PromiseId aPromiseId);
|
||||||
|
|
||||||
|
// Main thread only.
|
||||||
|
// Uses the CDM to create a key session.
|
||||||
|
// Caller is responsible for calling aInitData.ComputeLengthAndData().
|
||||||
|
// Calls MediaKeys::OnSessionActivated() when session is created.
|
||||||
|
void CreateSession(dom::SessionType aSessionType,
|
||||||
|
PromiseId aPromiseId,
|
||||||
|
const nsAString& aInitDataType,
|
||||||
|
const Uint8Array& aInitData);
|
||||||
|
|
||||||
|
// Main thread only.
|
||||||
|
// Uses the CDM to load a presistent session stored on disk.
|
||||||
|
// Calls MediaKeys::OnSessionActivated() when session is loaded.
|
||||||
|
void LoadSession(PromiseId aPromiseId,
|
||||||
|
const nsAString& aSessionId);
|
||||||
|
|
||||||
|
// Main thread only.
|
||||||
|
// Sends a new certificate to the CDM.
|
||||||
|
// Caller is responsible for calling aCert.ComputeLengthAndData().
|
||||||
|
// Calls MediaKeys->ResolvePromise(aPromiseId) after the CDM has
|
||||||
|
// processed the request.
|
||||||
|
void SetServerCertificate(PromiseId aPromiseId,
|
||||||
|
const Uint8Array& aCert);
|
||||||
|
|
||||||
|
// Main thread only.
|
||||||
|
// Sends an update to the CDM.
|
||||||
|
// Caller is responsible for calling aResponse.ComputeLengthAndData().
|
||||||
|
// Calls MediaKeys->ResolvePromise(aPromiseId) after the CDM has
|
||||||
|
// processed the request.
|
||||||
|
void UpdateSession(const nsAString& aSessionId,
|
||||||
|
PromiseId aPromiseId,
|
||||||
|
const Uint8Array& aResponse);
|
||||||
|
|
||||||
|
// Main thread only.
|
||||||
|
// Calls MediaKeys->ResolvePromise(aPromiseId) after the CDM has
|
||||||
|
// processed the request.
|
||||||
|
// If processing this operation results in the session actually closing,
|
||||||
|
// we also call MediaKeySession::OnClosed(), which in turn calls
|
||||||
|
// MediaKeys::OnSessionClosed().
|
||||||
|
void CloseSession(const nsAString& aSessionId,
|
||||||
|
PromiseId aPromiseId);
|
||||||
|
|
||||||
|
// Main thread only.
|
||||||
|
// Removes all data for a persisent session.
|
||||||
|
// Calls MediaKeys->ResolvePromise(aPromiseId) after the CDM has
|
||||||
|
// processed the request.
|
||||||
|
void RemoveSession(const nsAString& aSessionId,
|
||||||
|
PromiseId aPromiseId);
|
||||||
|
|
||||||
|
// Main thread only.
|
||||||
|
void Shutdown();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
class RejectPromiseTask : public nsRunnable {
|
||||||
|
public:
|
||||||
|
RejectPromiseTask(CDMProxy* aProxy,
|
||||||
|
PromiseId aId,
|
||||||
|
nsresult aCode)
|
||||||
|
: mProxy(aProxy)
|
||||||
|
, mId(aId)
|
||||||
|
, mCode(aCode)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
NS_METHOD Run() {
|
||||||
|
mProxy->RejectPromise(mId, mCode);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
nsRefPtr<CDMProxy> mProxy;
|
||||||
|
PromiseId mId;
|
||||||
|
nsresult mCode;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Reject promise with DOMException corresponding to aExceptionCode.
|
||||||
|
// Can be called from any thread.
|
||||||
|
void RejectPromise(PromiseId aId, nsresult aExceptionCode);
|
||||||
|
// Resolves promise with "undefined".
|
||||||
|
// Can be called from any thread.
|
||||||
|
void ResolvePromise(PromiseId aId);
|
||||||
|
|
||||||
|
~CDMProxy();
|
||||||
|
|
||||||
|
// Helper to enforce that a raw pointer is only accessed on the main thread.
|
||||||
|
template<class Type>
|
||||||
|
class MainThreadOnlyRawPtr {
|
||||||
|
public:
|
||||||
|
MainThreadOnlyRawPtr(Type* aPtr)
|
||||||
|
: mPtr(aPtr)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsNull() const {
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
return !mPtr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Clear() {
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
mPtr = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Type* operator->() const {
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
return mPtr;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
Type* mPtr;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Our reference back to the MediaKeys object.
|
||||||
|
// WARNING: This is a non-owning reference that is cleared by MediaKeys
|
||||||
|
// destructor. only use on main thread, and always nullcheck before using!
|
||||||
|
MainThreadOnlyRawPtr<dom::MediaKeys> mKeys;
|
||||||
|
|
||||||
|
const nsAutoString mKeySystem;
|
||||||
|
|
||||||
|
// Gecko Media Plugin thread. All interactions with the out-of-process
|
||||||
|
// EME plugin must come from this thread.
|
||||||
|
nsRefPtr<nsIThread> mGMPThread;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
|
#endif // CDMProxy_h_
|
|
@ -0,0 +1,32 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#include "EMELog.h"
|
||||||
|
#include "mozilla/NullPtr.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
|
||||||
|
#ifdef PR_LOGGING
|
||||||
|
|
||||||
|
PRLogModuleInfo* GetEMELog() {
|
||||||
|
static PRLogModuleInfo* log = nullptr;
|
||||||
|
if (!log) {
|
||||||
|
log = PR_NewLogModule("EME");
|
||||||
|
}
|
||||||
|
return log;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRLogModuleInfo* GetEMEVerboseLog() {
|
||||||
|
static PRLogModuleInfo* log = nullptr;
|
||||||
|
if (!log) {
|
||||||
|
log = PR_NewLogModule("EMEV");
|
||||||
|
}
|
||||||
|
return log;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace mozilla
|
|
@ -0,0 +1,35 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#include "prlog.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
|
||||||
|
#ifdef PR_LOGGING
|
||||||
|
|
||||||
|
#ifndef EME_LOG
|
||||||
|
PRLogModuleInfo* GetEMELog();
|
||||||
|
#define EME_LOG(...) PR_LOG(GetEMELog(), PR_LOG_DEBUG, (__VA_ARGS__))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef EME_VERBOSE_LOG
|
||||||
|
PRLogModuleInfo* GetEMEVerboseLog();
|
||||||
|
#define EME_VERBOSE_LOG(...) PR_LOG(GetEMEVerboseLog(), PR_LOG_DEBUG, (__VA_ARGS__))
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#ifndef EME_LOG
|
||||||
|
#define EME_LOG(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef EME_VERBOSE_LOG
|
||||||
|
#define EME_VERBOSE_LOG(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // PR_LOGGING
|
||||||
|
} // namespace mozilla
|
|
@ -0,0 +1,39 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#include "MediaKeyError.h"
|
||||||
|
#include "mozilla/dom/MediaKeyErrorBinding.h"
|
||||||
|
#include "nsContentUtils.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
|
||||||
|
MediaKeyError::MediaKeyError(EventTarget* aOwner, uint32_t aSystemCode)
|
||||||
|
: Event(aOwner, nullptr, nullptr)
|
||||||
|
, mSystemCode(aSystemCode)
|
||||||
|
{
|
||||||
|
SetIsDOMBinding();
|
||||||
|
}
|
||||||
|
|
||||||
|
MediaKeyError::~MediaKeyError()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
MediaKeyError::SystemCode() const
|
||||||
|
{
|
||||||
|
return mSystemCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
JSObject*
|
||||||
|
MediaKeyError::WrapObject(JSContext* aCx)
|
||||||
|
{
|
||||||
|
return MediaKeyErrorBinding::Wrap(aCx, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
|
@ -0,0 +1,38 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#ifndef mozilla_dom_MediaKeyError_h
|
||||||
|
#define mozilla_dom_MediaKeyError_h
|
||||||
|
|
||||||
|
#include "mozilla/Attributes.h"
|
||||||
|
#include "mozilla/ErrorResult.h"
|
||||||
|
#include "nsWrapperCache.h"
|
||||||
|
#include "mozilla/dom/Event.h"
|
||||||
|
#include "js/TypeDecls.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
|
||||||
|
class MediaKeyError MOZ_FINAL : public Event
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NS_FORWARD_TO_EVENT
|
||||||
|
|
||||||
|
MediaKeyError(EventTarget* aOwner, uint32_t aSystemCode);
|
||||||
|
~MediaKeyError();
|
||||||
|
|
||||||
|
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
uint32_t SystemCode() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32_t mSystemCode;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,127 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#include "mozilla/dom/MediaKeyMessageEvent.h"
|
||||||
|
#include "mozilla/dom/MediaKeyMessageEventBinding.h"
|
||||||
|
#include "js/GCAPI.h"
|
||||||
|
#include "jsfriendapi.h"
|
||||||
|
#include "mozilla/dom/Nullable.h"
|
||||||
|
#include "mozilla/dom/PrimitiveConversions.h"
|
||||||
|
#include "mozilla/HoldDropJSObjects.h"
|
||||||
|
#include "mozilla/dom/TypedArray.h"
|
||||||
|
#include "nsContentUtils.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_CLASS(MediaKeyMessageEvent)
|
||||||
|
|
||||||
|
NS_IMPL_ADDREF_INHERITED(MediaKeyMessageEvent, Event)
|
||||||
|
NS_IMPL_RELEASE_INHERITED(MediaKeyMessageEvent, Event)
|
||||||
|
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(MediaKeyMessageEvent, Event)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||||
|
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(MediaKeyMessageEvent, Event)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mMessage)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||||
|
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(MediaKeyMessageEvent, Event)
|
||||||
|
tmp->mMessage = nullptr;
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||||
|
|
||||||
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(MediaKeyMessageEvent)
|
||||||
|
NS_INTERFACE_MAP_END_INHERITING(Event)
|
||||||
|
|
||||||
|
MediaKeyMessageEvent::MediaKeyMessageEvent(EventTarget* aOwner)
|
||||||
|
: Event(aOwner, nullptr, nullptr)
|
||||||
|
{
|
||||||
|
mozilla::HoldJSObjects(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
MediaKeyMessageEvent::~MediaKeyMessageEvent()
|
||||||
|
{
|
||||||
|
mMessage = nullptr;
|
||||||
|
mozilla::DropJSObjects(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
MediaKeyMessageEvent*
|
||||||
|
MediaKeyMessageEvent::AsMediaKeyMessageEvent()
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
JSObject*
|
||||||
|
MediaKeyMessageEvent::WrapObject(JSContext* aCx)
|
||||||
|
{
|
||||||
|
return MediaKeyMessageEventBinding::Wrap(aCx, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
already_AddRefed<MediaKeyMessageEvent>
|
||||||
|
MediaKeyMessageEvent::Constructor(EventTarget* aOwner,
|
||||||
|
const nsAString& aURL,
|
||||||
|
const nsTArray<uint8_t>& aMessage)
|
||||||
|
{
|
||||||
|
nsRefPtr<MediaKeyMessageEvent> e = new MediaKeyMessageEvent(aOwner);
|
||||||
|
e->InitEvent(NS_LITERAL_STRING("message"), false, false);
|
||||||
|
e->mRawMessage = aMessage;
|
||||||
|
e->mDestinationURL = aURL;
|
||||||
|
e->SetTrusted(true);
|
||||||
|
return e.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
already_AddRefed<MediaKeyMessageEvent>
|
||||||
|
MediaKeyMessageEvent::Constructor(const GlobalObject& aGlobal,
|
||||||
|
const nsAString& aType,
|
||||||
|
const MediaKeyMessageEventInit& aEventInitDict,
|
||||||
|
ErrorResult& aRv)
|
||||||
|
{
|
||||||
|
nsCOMPtr<EventTarget> owner = do_QueryInterface(aGlobal.GetAsSupports());
|
||||||
|
nsRefPtr<MediaKeyMessageEvent> e = new MediaKeyMessageEvent(owner);
|
||||||
|
bool trusted = e->Init(owner);
|
||||||
|
e->InitEvent(aType, aEventInitDict.mBubbles, aEventInitDict.mCancelable);
|
||||||
|
if (aEventInitDict.mMessage.WasPassed()) {
|
||||||
|
const auto& a = aEventInitDict.mMessage.Value();
|
||||||
|
a.ComputeLengthAndData();
|
||||||
|
e->mMessage = Uint8Array::Create(aGlobal.GetContext(), owner, a.Length(), a.Data());
|
||||||
|
} else {
|
||||||
|
e->mMessage = Uint8Array::Create(aGlobal.GetContext(), owner, 0, nullptr);
|
||||||
|
}
|
||||||
|
if (!e->mMessage) {
|
||||||
|
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
e->mDestinationURL = aEventInitDict.mDestinationURL;
|
||||||
|
e->SetTrusted(trusted);
|
||||||
|
return e.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
JSObject*
|
||||||
|
MediaKeyMessageEvent::GetMessage(JSContext* cx, ErrorResult& aRv)
|
||||||
|
{
|
||||||
|
if (!mMessage) {
|
||||||
|
mMessage = Uint8Array::Create(cx,
|
||||||
|
this,
|
||||||
|
mRawMessage.Length(),
|
||||||
|
mRawMessage.Elements());
|
||||||
|
if (!mMessage) {
|
||||||
|
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
mRawMessage.Clear();
|
||||||
|
}
|
||||||
|
JS::ExposeObjectToActiveJS(mMessage);
|
||||||
|
return mMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MediaKeyMessageEvent::GetDestinationURL(nsString& aRetVal) const
|
||||||
|
{
|
||||||
|
aRetVal = mDestinationURL;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
|
@ -0,0 +1,65 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#ifndef mozilla_dom_MediaKeyMessageEvent_h__
|
||||||
|
#define mozilla_dom_MediaKeyMessageEvent_h__
|
||||||
|
|
||||||
|
#include "mozilla/Attributes.h"
|
||||||
|
#include "mozilla/ErrorResult.h"
|
||||||
|
#include "nsCycleCollectionParticipant.h"
|
||||||
|
#include "nsWrapperCache.h"
|
||||||
|
#include "nsCOMPtr.h"
|
||||||
|
#include "mozilla/dom/Event.h"
|
||||||
|
#include "mozilla/dom/TypedArray.h"
|
||||||
|
#include "js/TypeDecls.h"
|
||||||
|
#include "mozilla/dom/MediaKeyMessageEventBinding.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
|
||||||
|
class MediaKeyMessageEventInit;
|
||||||
|
|
||||||
|
class MediaKeyMessageEvent MOZ_FINAL : public Event
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NS_DECL_ISUPPORTS_INHERITED
|
||||||
|
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(MediaKeyMessageEvent, Event)
|
||||||
|
virtual ~MediaKeyMessageEvent();
|
||||||
|
protected:
|
||||||
|
MediaKeyMessageEvent(EventTarget* aOwner);
|
||||||
|
|
||||||
|
JS::Heap<JSObject*> mMessage;
|
||||||
|
nsString mDestinationURL;
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual MediaKeyMessageEvent* AsMediaKeyMessageEvent();
|
||||||
|
|
||||||
|
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
static already_AddRefed<MediaKeyMessageEvent>
|
||||||
|
Constructor(EventTarget* aOwner,
|
||||||
|
const nsAString& aURL,
|
||||||
|
const nsTArray<uint8_t>& aMessage);
|
||||||
|
|
||||||
|
static already_AddRefed<MediaKeyMessageEvent>
|
||||||
|
Constructor(const GlobalObject& aGlobal,
|
||||||
|
const nsAString& aType,
|
||||||
|
const MediaKeyMessageEventInit& aEventInitDict,
|
||||||
|
ErrorResult& aRv);
|
||||||
|
|
||||||
|
JSObject* GetMessage(JSContext* cx, ErrorResult& aRv);
|
||||||
|
|
||||||
|
void GetDestinationURL(nsString& aRetVal) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
nsTArray<uint8_t> mRawMessage;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
|
#endif // mozilla_dom_MediaKeyMessageEvent_h__
|
|
@ -0,0 +1,118 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#include "MediaKeyNeededEvent.h"
|
||||||
|
#include "mozilla/dom/MediaKeyNeededEventBinding.h"
|
||||||
|
#include "nsContentUtils.h"
|
||||||
|
#include "jsfriendapi.h"
|
||||||
|
#include "nsINode.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_CLASS(MediaKeyNeededEvent)
|
||||||
|
|
||||||
|
NS_IMPL_ADDREF_INHERITED(MediaKeyNeededEvent, Event)
|
||||||
|
NS_IMPL_RELEASE_INHERITED(MediaKeyNeededEvent, Event)
|
||||||
|
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(MediaKeyNeededEvent, Event)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||||
|
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(MediaKeyNeededEvent, Event)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mInitData)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||||
|
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(MediaKeyNeededEvent, Event)
|
||||||
|
tmp->mInitData = nullptr;
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||||
|
|
||||||
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(MediaKeyNeededEvent)
|
||||||
|
NS_INTERFACE_MAP_END_INHERITING(Event)
|
||||||
|
|
||||||
|
MediaKeyNeededEvent::MediaKeyNeededEvent(EventTarget* aOwner)
|
||||||
|
: Event(aOwner, nullptr, nullptr)
|
||||||
|
{
|
||||||
|
mozilla::HoldJSObjects(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
MediaKeyNeededEvent::~MediaKeyNeededEvent()
|
||||||
|
{
|
||||||
|
mInitData = nullptr;
|
||||||
|
mozilla::DropJSObjects(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
JSObject*
|
||||||
|
MediaKeyNeededEvent::WrapObject(JSContext* aCx)
|
||||||
|
{
|
||||||
|
return MediaKeyNeededEventBinding::Wrap(aCx, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
already_AddRefed<MediaKeyNeededEvent>
|
||||||
|
MediaKeyNeededEvent::Constructor(EventTarget* aOwner,
|
||||||
|
const nsAString& aInitDataType,
|
||||||
|
const nsTArray<uint8_t>& aInitData)
|
||||||
|
{
|
||||||
|
nsRefPtr<MediaKeyNeededEvent> e = new MediaKeyNeededEvent(aOwner);
|
||||||
|
e->InitEvent(NS_LITERAL_STRING("needkey"), false, false);
|
||||||
|
e->mInitDataType = aInitDataType;
|
||||||
|
e->mRawInitData = aInitData;
|
||||||
|
e->SetTrusted(true);
|
||||||
|
return e.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
already_AddRefed<MediaKeyNeededEvent>
|
||||||
|
MediaKeyNeededEvent::Constructor(const GlobalObject& aGlobal,
|
||||||
|
const nsAString& aType,
|
||||||
|
const MediaKeyNeededEventInit& aEventInitDict,
|
||||||
|
ErrorResult& aRv)
|
||||||
|
{
|
||||||
|
nsCOMPtr<EventTarget> owner = do_QueryInterface(aGlobal.GetAsSupports());
|
||||||
|
nsRefPtr<MediaKeyNeededEvent> e = new MediaKeyNeededEvent(owner);
|
||||||
|
bool trusted = e->Init(owner);
|
||||||
|
e->InitEvent(aType, aEventInitDict.mBubbles, aEventInitDict.mCancelable);
|
||||||
|
e->mInitDataType = aEventInitDict.mInitDataType;
|
||||||
|
if (aEventInitDict.mInitData.WasPassed() &&
|
||||||
|
!aEventInitDict.mInitData.Value().IsNull()) {
|
||||||
|
const auto& a = aEventInitDict.mInitData.Value().Value();
|
||||||
|
a.ComputeLengthAndData();
|
||||||
|
e->mInitData = Uint8Array::Create(aGlobal.GetContext(), owner, a.Length(), a.Data());
|
||||||
|
if (!e->mInitData) {
|
||||||
|
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
e->SetTrusted(trusted);
|
||||||
|
return e.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MediaKeyNeededEvent::GetInitDataType(nsString& aRetVal) const
|
||||||
|
{
|
||||||
|
aRetVal = mInitDataType;
|
||||||
|
}
|
||||||
|
|
||||||
|
JSObject*
|
||||||
|
MediaKeyNeededEvent::GetInitData(JSContext* cx, ErrorResult& aRv)
|
||||||
|
{
|
||||||
|
if (mRawInitData.Length()) {
|
||||||
|
mInitData = Uint8Array::Create(cx,
|
||||||
|
this,
|
||||||
|
mRawInitData.Length(),
|
||||||
|
mRawInitData.Elements());
|
||||||
|
if (!mInitData) {
|
||||||
|
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
mRawInitData.Clear();
|
||||||
|
}
|
||||||
|
if (mInitData) {
|
||||||
|
JS::ExposeObjectToActiveJS(mInitData);
|
||||||
|
}
|
||||||
|
return mInitData;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
|
@ -0,0 +1,62 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#ifndef mozilla_dom_MediaKeyNeededEvent_h__
|
||||||
|
#define mozilla_dom_MediaKeyNeededEvent_h__
|
||||||
|
|
||||||
|
#include "mozilla/dom/MediaKeyNeededEventBinding.h"
|
||||||
|
#include "mozilla/Attributes.h"
|
||||||
|
#include "mozilla/ErrorResult.h"
|
||||||
|
#include "nsCycleCollectionParticipant.h"
|
||||||
|
#include "nsWrapperCache.h"
|
||||||
|
#include "nsCOMPtr.h"
|
||||||
|
#include "mozilla/dom/Event.h"
|
||||||
|
#include "mozilla/dom/TypedArray.h"
|
||||||
|
#include "mozilla/Attributes.h"
|
||||||
|
#include "mozilla/dom/BindingUtils.h"
|
||||||
|
#include "js/TypeDecls.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
|
||||||
|
class MediaKeyNeededEvent MOZ_FINAL : public Event
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NS_DECL_ISUPPORTS_INHERITED
|
||||||
|
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(MediaKeyNeededEvent, Event)
|
||||||
|
virtual ~MediaKeyNeededEvent();
|
||||||
|
protected:
|
||||||
|
MediaKeyNeededEvent(EventTarget* aOwner);
|
||||||
|
|
||||||
|
nsString mInitDataType;
|
||||||
|
JS::Heap<JSObject*> mInitData;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
static already_AddRefed<MediaKeyNeededEvent>
|
||||||
|
Constructor(EventTarget* aOwner,
|
||||||
|
const nsAString& aInitDataType,
|
||||||
|
const nsTArray<uint8_t>& aInitData);
|
||||||
|
|
||||||
|
static already_AddRefed<MediaKeyNeededEvent>
|
||||||
|
Constructor(const GlobalObject& aGlobal,
|
||||||
|
const nsAString& aType,
|
||||||
|
const MediaKeyNeededEventInit& aEventInitDict,
|
||||||
|
ErrorResult& aRv);
|
||||||
|
|
||||||
|
void GetInitDataType(nsString& aRetVal) const;
|
||||||
|
|
||||||
|
JSObject* GetInitData(JSContext* cx, ErrorResult& aRv);
|
||||||
|
private:
|
||||||
|
nsTArray<uint8_t> mRawInitData;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
|
#endif // mozilla_dom_MediaKeyNeededEvent_h__
|
|
@ -0,0 +1,178 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#include "mozilla/dom/HTMLMediaElement.h"
|
||||||
|
#include "mozilla/dom/MediaKeySession.h"
|
||||||
|
#include "mozilla/dom/MediaKeyError.h"
|
||||||
|
#include "mozilla/dom/MediaKeyMessageEvent.h"
|
||||||
|
#include "mozilla/dom/MediaKeyNeededEvent.h"
|
||||||
|
#include "nsCycleCollectionParticipant.h"
|
||||||
|
#include "mozilla/CDMProxy.h"
|
||||||
|
#include "mozilla/AsyncEventDispatcher.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_INHERITED(MediaKeySession,
|
||||||
|
DOMEventTargetHelper,
|
||||||
|
mMediaKeyError,
|
||||||
|
mKeys,
|
||||||
|
mClosed)
|
||||||
|
|
||||||
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(MediaKeySession)
|
||||||
|
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
|
||||||
|
|
||||||
|
NS_IMPL_ADDREF_INHERITED(MediaKeySession, DOMEventTargetHelper)
|
||||||
|
NS_IMPL_RELEASE_INHERITED(MediaKeySession, DOMEventTargetHelper)
|
||||||
|
|
||||||
|
MediaKeySession::MediaKeySession(nsPIDOMWindow* aParent,
|
||||||
|
MediaKeys* aKeys,
|
||||||
|
const nsAString& aKeySystem,
|
||||||
|
SessionType aSessionType)
|
||||||
|
: DOMEventTargetHelper(aParent)
|
||||||
|
, mKeys(aKeys)
|
||||||
|
, mKeySystem(aKeySystem)
|
||||||
|
, mSessionType(aSessionType)
|
||||||
|
, mIsClosed(false)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(aParent);
|
||||||
|
mClosed = mKeys->MakePromise();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MediaKeySession::Init(const nsAString& aSessionId)
|
||||||
|
{
|
||||||
|
mSessionId = aSessionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
MediaKeySession::~MediaKeySession()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
MediaKeyError*
|
||||||
|
MediaKeySession::GetError() const
|
||||||
|
{
|
||||||
|
return mMediaKeyError;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MediaKeySession::GetKeySystem(nsString& aKeySystem) const
|
||||||
|
{
|
||||||
|
aKeySystem = mKeySystem;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MediaKeySession::GetSessionId(nsString& aSessionId) const
|
||||||
|
{
|
||||||
|
aSessionId = mSessionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
JSObject*
|
||||||
|
MediaKeySession::WrapObject(JSContext* aCx)
|
||||||
|
{
|
||||||
|
return MediaKeySessionBinding::Wrap(aCx, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
double
|
||||||
|
MediaKeySession::Expiration() const
|
||||||
|
{
|
||||||
|
return JS::GenericNaN();
|
||||||
|
}
|
||||||
|
|
||||||
|
Promise*
|
||||||
|
MediaKeySession::Closed() const
|
||||||
|
{
|
||||||
|
return mClosed;
|
||||||
|
}
|
||||||
|
|
||||||
|
already_AddRefed<Promise>
|
||||||
|
MediaKeySession::Update(const Uint8Array& aResponse)
|
||||||
|
{
|
||||||
|
nsRefPtr<Promise> promise(mKeys->MakePromise());
|
||||||
|
aResponse.ComputeLengthAndData();
|
||||||
|
if (IsClosed() ||
|
||||||
|
!mKeys->GetCDMProxy() ||
|
||||||
|
!aResponse.Length()) {
|
||||||
|
promise->MaybeReject(NS_ERROR_DOM_INVALID_ACCESS_ERR);
|
||||||
|
return promise.forget();
|
||||||
|
}
|
||||||
|
mKeys->GetCDMProxy()->UpdateSession(mSessionId,
|
||||||
|
mKeys->StorePromise(promise),
|
||||||
|
aResponse);
|
||||||
|
return promise.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
already_AddRefed<Promise>
|
||||||
|
MediaKeySession::Close()
|
||||||
|
{
|
||||||
|
nsRefPtr<Promise> promise(mKeys->MakePromise());
|
||||||
|
if (IsClosed() || !mKeys->GetCDMProxy()) {
|
||||||
|
promise->MaybeResolve(JS::UndefinedHandleValue);
|
||||||
|
return promise.forget();
|
||||||
|
}
|
||||||
|
mKeys->GetCDMProxy()->CloseSession(mSessionId, mKeys->StorePromise(promise));
|
||||||
|
|
||||||
|
return promise.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MediaKeySession::OnClosed()
|
||||||
|
{
|
||||||
|
if (IsClosed()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mIsClosed = true;
|
||||||
|
// TODO: reset usableKeyIds
|
||||||
|
mKeys->OnSessionClosed(this);
|
||||||
|
mKeys = nullptr;
|
||||||
|
mClosed->MaybeResolve(JS::UndefinedHandleValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
MediaKeySession::IsClosed() const
|
||||||
|
{
|
||||||
|
return mIsClosed;
|
||||||
|
}
|
||||||
|
|
||||||
|
already_AddRefed<Promise>
|
||||||
|
MediaKeySession::Remove()
|
||||||
|
{
|
||||||
|
nsRefPtr<Promise> promise(mKeys->MakePromise());
|
||||||
|
if (mSessionType != SessionType::Persistent) {
|
||||||
|
promise->MaybeReject(NS_ERROR_DOM_INVALID_ACCESS_ERR);
|
||||||
|
// "The operation is not supported on session type sessions."
|
||||||
|
return promise.forget();
|
||||||
|
}
|
||||||
|
if (IsClosed() || !mKeys->GetCDMProxy()) {
|
||||||
|
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||||
|
// "The session is closed."
|
||||||
|
return promise.forget();
|
||||||
|
}
|
||||||
|
mKeys->GetCDMProxy()->RemoveSession(mSessionId, mKeys->StorePromise(promise));
|
||||||
|
return promise.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MediaKeySession::DispatchKeyMessage(const nsTArray<uint8_t>& aMessage,
|
||||||
|
const nsString& aURL)
|
||||||
|
{
|
||||||
|
nsRefPtr<MediaKeyMessageEvent> event(
|
||||||
|
MediaKeyMessageEvent::Constructor(this, aURL, aMessage));
|
||||||
|
nsRefPtr<AsyncEventDispatcher> asyncDispatcher =
|
||||||
|
new AsyncEventDispatcher(this, event);
|
||||||
|
asyncDispatcher->PostDOMEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MediaKeySession::DispatchKeyError(uint32_t aSystemCode)
|
||||||
|
{
|
||||||
|
RefPtr<MediaKeyError> event(new MediaKeyError(this, aSystemCode));
|
||||||
|
nsRefPtr<AsyncEventDispatcher> asyncDispatcher =
|
||||||
|
new AsyncEventDispatcher(this, event);
|
||||||
|
asyncDispatcher->PostDOMEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
|
@ -0,0 +1,93 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#ifndef mozilla_dom_MediaKeySession_h
|
||||||
|
#define mozilla_dom_MediaKeySession_h
|
||||||
|
|
||||||
|
#include "mozilla/Attributes.h"
|
||||||
|
#include "mozilla/ErrorResult.h"
|
||||||
|
#include "nsCycleCollectionParticipant.h"
|
||||||
|
#include "mozilla/DOMEventTargetHelper.h"
|
||||||
|
#include "nsCOMPtr.h"
|
||||||
|
#include "mozilla/dom/TypedArray.h"
|
||||||
|
#include "mozilla/Mutex.h"
|
||||||
|
#include "mozilla/dom/Date.h"
|
||||||
|
#include "mozilla/dom/Promise.h"
|
||||||
|
#include "mozilla/dom/MediaKeySessionBinding.h"
|
||||||
|
#include "mozilla/dom/MediaKeysBinding.h"
|
||||||
|
|
||||||
|
struct JSContext;
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
|
||||||
|
class CDMProxy;
|
||||||
|
|
||||||
|
namespace dom {
|
||||||
|
|
||||||
|
class MediaKeyError;
|
||||||
|
|
||||||
|
class MediaKeySession MOZ_FINAL : public DOMEventTargetHelper
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NS_DECL_ISUPPORTS_INHERITED
|
||||||
|
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(MediaKeySession,
|
||||||
|
DOMEventTargetHelper)
|
||||||
|
public:
|
||||||
|
MediaKeySession(nsPIDOMWindow* aParent,
|
||||||
|
MediaKeys* aKeys,
|
||||||
|
const nsAString& aKeySystem,
|
||||||
|
SessionType aSessionType);
|
||||||
|
|
||||||
|
void Init(const nsAString& aSessionId);
|
||||||
|
|
||||||
|
~MediaKeySession();
|
||||||
|
|
||||||
|
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
// Mark this as resultNotAddRefed to return raw pointers
|
||||||
|
MediaKeyError* GetError() const;
|
||||||
|
|
||||||
|
void GetKeySystem(nsString& aRetval) const;
|
||||||
|
|
||||||
|
void GetSessionId(nsString& aRetval) const;
|
||||||
|
|
||||||
|
// Number of ms since epoch at which expiration occurs, or NaN if unknown.
|
||||||
|
// TODO: The type of this attribute is still under contention.
|
||||||
|
// https://www.w3.org/Bugs/Public/show_bug.cgi?id=25902
|
||||||
|
double Expiration() const;
|
||||||
|
|
||||||
|
Promise* Closed() const;
|
||||||
|
|
||||||
|
already_AddRefed<Promise> Update(const Uint8Array& response);
|
||||||
|
|
||||||
|
already_AddRefed<Promise> Close();
|
||||||
|
|
||||||
|
already_AddRefed<Promise> Remove();
|
||||||
|
|
||||||
|
void DispatchKeyMessage(const nsTArray<uint8_t>& aMessage,
|
||||||
|
const nsString& aURL);
|
||||||
|
|
||||||
|
void DispatchKeyError(uint32_t system_code);
|
||||||
|
|
||||||
|
void OnClosed();
|
||||||
|
|
||||||
|
bool IsClosed() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
nsRefPtr<Promise> mClosed;
|
||||||
|
|
||||||
|
nsRefPtr<MediaKeyError> mMediaKeyError;
|
||||||
|
nsRefPtr<MediaKeys> mKeys;
|
||||||
|
const nsString mKeySystem;
|
||||||
|
nsString mSessionId;
|
||||||
|
const SessionType mSessionType;
|
||||||
|
bool mIsClosed;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,291 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#include "mozilla/dom/HTMLMediaElement.h"
|
||||||
|
#include "mozilla/dom/MediaKeys.h"
|
||||||
|
#include "mozilla/dom/MediaKeysBinding.h"
|
||||||
|
#include "mozilla/dom/MediaKeyMessageEvent.h"
|
||||||
|
#include "mozilla/dom/MediaKeyError.h"
|
||||||
|
#include "mozilla/dom/MediaKeySession.h"
|
||||||
|
#include "mozilla/dom/DOMException.h"
|
||||||
|
#include "mozilla/CDMProxy.h"
|
||||||
|
#include "nsContentUtils.h"
|
||||||
|
#include "EMELog.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
|
||||||
|
namespace dom {
|
||||||
|
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(MediaKeys,
|
||||||
|
mParent,
|
||||||
|
mKeySessions,
|
||||||
|
mPromises,
|
||||||
|
mPendingSessions);
|
||||||
|
NS_IMPL_CYCLE_COLLECTING_ADDREF(MediaKeys)
|
||||||
|
NS_IMPL_CYCLE_COLLECTING_RELEASE(MediaKeys)
|
||||||
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MediaKeys)
|
||||||
|
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||||
|
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||||
|
NS_INTERFACE_MAP_END
|
||||||
|
|
||||||
|
MediaKeys::MediaKeys(nsPIDOMWindow* aParent, const nsAString& aKeySystem)
|
||||||
|
: mParent(aParent),
|
||||||
|
mKeySystem(aKeySystem)
|
||||||
|
{
|
||||||
|
SetIsDOMBinding();
|
||||||
|
}
|
||||||
|
|
||||||
|
MediaKeys::~MediaKeys()
|
||||||
|
{
|
||||||
|
if (mProxy) {
|
||||||
|
mProxy->Shutdown();
|
||||||
|
mProxy = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nsPIDOMWindow*
|
||||||
|
MediaKeys::GetParentObject() const
|
||||||
|
{
|
||||||
|
return mParent;
|
||||||
|
}
|
||||||
|
|
||||||
|
JSObject*
|
||||||
|
MediaKeys::WrapObject(JSContext* aCx)
|
||||||
|
{
|
||||||
|
return MediaKeysBinding::Wrap(aCx, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MediaKeys::GetKeySystem(nsString& retval) const
|
||||||
|
{
|
||||||
|
retval = mKeySystem;
|
||||||
|
}
|
||||||
|
|
||||||
|
already_AddRefed<Promise>
|
||||||
|
MediaKeys::SetServerCertificate(const Uint8Array& aCert)
|
||||||
|
{
|
||||||
|
aCert.ComputeLengthAndData();
|
||||||
|
nsRefPtr<Promise> promise(MakePromise());
|
||||||
|
mProxy->SetServerCertificate(StorePromise(promise), aCert);
|
||||||
|
return promise.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static */
|
||||||
|
IsTypeSupportedResult
|
||||||
|
MediaKeys::IsTypeSupported(const GlobalObject& aGlobal,
|
||||||
|
const nsAString& aKeySystem,
|
||||||
|
const Optional<nsAString>& aInitDataType,
|
||||||
|
const Optional<nsAString>& aContentType,
|
||||||
|
const Optional<nsAString>& aCapability)
|
||||||
|
{
|
||||||
|
// TODO: Query list of known CDMs and their supported content types.
|
||||||
|
// TODO: Should really get spec changed to this is async, so we can wait
|
||||||
|
// for user to consent to running plugin.
|
||||||
|
return IsTypeSupportedResult::Maybe;
|
||||||
|
}
|
||||||
|
|
||||||
|
already_AddRefed<Promise>
|
||||||
|
MediaKeys::MakePromise()
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetParentObject());
|
||||||
|
if (!global) {
|
||||||
|
NS_WARNING("Passed non-global to MediaKeys ctor!");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
nsRefPtr<Promise> promise = new Promise(global);
|
||||||
|
return promise.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
PromiseId
|
||||||
|
MediaKeys::StorePromise(Promise* aPromise)
|
||||||
|
{
|
||||||
|
static uint32_t sEMEPromiseCount = 1;
|
||||||
|
MOZ_ASSERT(aPromise);
|
||||||
|
uint32_t id = sEMEPromiseCount++;
|
||||||
|
mPromises.Put(id, aPromise);
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
already_AddRefed<Promise>
|
||||||
|
MediaKeys::RetrievePromise(PromiseId aId)
|
||||||
|
{
|
||||||
|
nsRefPtr<Promise> promise;
|
||||||
|
mPromises.Remove(aId, getter_AddRefs(promise));
|
||||||
|
return promise.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MediaKeys::RejectPromise(PromiseId aId, nsresult aExceptionCode)
|
||||||
|
{
|
||||||
|
nsRefPtr<Promise> promise(RetrievePromise(aId));
|
||||||
|
if (!promise) {
|
||||||
|
NS_WARNING("MediaKeys tried to reject a non-existent promise");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (mPendingSessions.Contains(aId)) {
|
||||||
|
// This promise could be a createSession or loadSession promise,
|
||||||
|
// so we might have a pending session waiting to be resolved into
|
||||||
|
// the promise on success. We've been directed to reject to promise,
|
||||||
|
// so we can throw away the corresponding session object.
|
||||||
|
mPendingSessions.Remove(aId);
|
||||||
|
}
|
||||||
|
|
||||||
|
MOZ_ASSERT(NS_FAILED(aExceptionCode));
|
||||||
|
promise->MaybeReject(aExceptionCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MediaKeys::ResolvePromise(PromiseId aId)
|
||||||
|
{
|
||||||
|
nsRefPtr<Promise> promise(RetrievePromise(aId));
|
||||||
|
if (!promise) {
|
||||||
|
NS_WARNING("MediaKeys tried to resolve a non-existent promise");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// We should not resolve CreateSession or LoadSession calls via this path,
|
||||||
|
// OnSessionActivated() should be called instead.
|
||||||
|
MOZ_ASSERT(!mPendingSessions.Contains(aId));
|
||||||
|
promise->MaybeResolve(JS::UndefinedHandleValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static */
|
||||||
|
already_AddRefed<Promise>
|
||||||
|
MediaKeys::Create(const GlobalObject& aGlobal,
|
||||||
|
const nsAString& aKeySystem,
|
||||||
|
ErrorResult& aRv)
|
||||||
|
{
|
||||||
|
// CDMProxy keeps MediaKeys alive until it resolves the promise and thus
|
||||||
|
// returns the MediaKeys object to JS.
|
||||||
|
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aGlobal.GetAsSupports());
|
||||||
|
if (!window) {
|
||||||
|
aRv.Throw(NS_ERROR_FAILURE);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsRefPtr<MediaKeys> keys = new MediaKeys(window, aKeySystem);
|
||||||
|
nsRefPtr<Promise> promise(keys->MakePromise());
|
||||||
|
if (!promise) {
|
||||||
|
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!aKeySystem.EqualsASCII("org.w3.clearkey")) {
|
||||||
|
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
keys->mProxy = new CDMProxy(keys, aKeySystem);
|
||||||
|
keys->mProxy->Init(keys->StorePromise(promise));
|
||||||
|
|
||||||
|
return promise.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MediaKeys::OnCDMCreated(PromiseId aId)
|
||||||
|
{
|
||||||
|
nsRefPtr<Promise> promise(RetrievePromise(aId));
|
||||||
|
if (!promise) {
|
||||||
|
NS_WARNING("MediaKeys tried to resolve a non-existent promise");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
nsRefPtr<MediaKeys> keys(this);
|
||||||
|
promise->MaybeResolve(keys);
|
||||||
|
}
|
||||||
|
|
||||||
|
already_AddRefed<Promise>
|
||||||
|
MediaKeys::LoadSession(const nsAString& aSessionId)
|
||||||
|
{
|
||||||
|
nsRefPtr<Promise> promise(MakePromise());
|
||||||
|
|
||||||
|
if (aSessionId.IsEmpty()) {
|
||||||
|
promise->MaybeReject(NS_ERROR_DOM_INVALID_ACCESS_ERR);
|
||||||
|
// "The sessionId parameter is empty."
|
||||||
|
return promise.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: The spec doesn't specify what to do in this case...
|
||||||
|
if (mKeySessions.Contains(aSessionId)) {
|
||||||
|
promise->MaybeReject(NS_ERROR_DOM_INVALID_ACCESS_ERR);
|
||||||
|
return promise.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create session.
|
||||||
|
nsRefPtr<MediaKeySession> session(
|
||||||
|
new MediaKeySession(GetParentObject(), this, mKeySystem, SessionType::Persistent));
|
||||||
|
|
||||||
|
// Proxy owns session object until resolving promise.
|
||||||
|
mProxy->LoadSession(StorePromise(promise),
|
||||||
|
aSessionId);
|
||||||
|
|
||||||
|
return promise.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
already_AddRefed<Promise>
|
||||||
|
MediaKeys::CreateSession(const nsAString& initDataType,
|
||||||
|
const Uint8Array& aInitData,
|
||||||
|
SessionType aSessionType)
|
||||||
|
{
|
||||||
|
aInitData.ComputeLengthAndData();
|
||||||
|
nsRefPtr<Promise> promise(MakePromise());
|
||||||
|
nsRefPtr<MediaKeySession> session = new MediaKeySession(GetParentObject(),
|
||||||
|
this,
|
||||||
|
mKeySystem,
|
||||||
|
aSessionType);
|
||||||
|
auto pid = StorePromise(promise);
|
||||||
|
// Hang onto session until the CDM has finished setting it up.
|
||||||
|
mPendingSessions.Put(pid, session);
|
||||||
|
mProxy->CreateSession(aSessionType,
|
||||||
|
pid,
|
||||||
|
initDataType,
|
||||||
|
aInitData);
|
||||||
|
|
||||||
|
return promise.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MediaKeys::OnSessionActivated(PromiseId aId, const nsAString& aSessionId)
|
||||||
|
{
|
||||||
|
nsRefPtr<Promise> promise(RetrievePromise(aId));
|
||||||
|
if (!promise) {
|
||||||
|
NS_WARNING("MediaKeys tried to resolve a non-existent promise");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
MOZ_ASSERT(mPendingSessions.Contains(aId));
|
||||||
|
|
||||||
|
nsRefPtr<MediaKeySession> session;
|
||||||
|
if (!mPendingSessions.Get(aId, getter_AddRefs(session)) || !session) {
|
||||||
|
NS_WARNING("Received activation for non-existent session!");
|
||||||
|
promise->MaybeReject(NS_ERROR_DOM_INVALID_ACCESS_ERR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Session has completed creation/loading, remove it from mPendingSessions,
|
||||||
|
// and resolve the promise with it. We store it in mKeySessions, so we can
|
||||||
|
// find it again if we need to send messages to it etc.
|
||||||
|
mPendingSessions.Remove(aId);
|
||||||
|
session->Init(aSessionId);
|
||||||
|
mKeySessions.Put(aSessionId, session);
|
||||||
|
promise->MaybeResolve(session);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MediaKeys::OnSessionClosed(MediaKeySession* aSession)
|
||||||
|
{
|
||||||
|
nsAutoString id;
|
||||||
|
aSession->GetSessionId(id);
|
||||||
|
mKeySessions.Remove(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
already_AddRefed<MediaKeySession>
|
||||||
|
MediaKeys::GetSession(const nsAString& aSessionId)
|
||||||
|
{
|
||||||
|
nsRefPtr<MediaKeySession> session;
|
||||||
|
mKeySessions.Get(aSessionId, getter_AddRefs(session));
|
||||||
|
return session.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
|
@ -0,0 +1,120 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#ifndef mozilla_dom_mediakeys_h__
|
||||||
|
#define mozilla_dom_mediakeys_h__
|
||||||
|
|
||||||
|
#include "nsIDOMMediaError.h"
|
||||||
|
#include "nsWrapperCache.h"
|
||||||
|
#include "nsISupports.h"
|
||||||
|
#include "mozilla/Attributes.h"
|
||||||
|
#include "mozilla/RefPtr.h"
|
||||||
|
#include "nsCOMPtr.h"
|
||||||
|
#include "nsCycleCollectionParticipant.h"
|
||||||
|
#include "nsRefPtrHashtable.h"
|
||||||
|
#include "mozilla/dom/Promise.h"
|
||||||
|
#include "mozilla/dom/MediaKeysBinding.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
|
||||||
|
class CDMProxy;
|
||||||
|
|
||||||
|
namespace dom {
|
||||||
|
|
||||||
|
class MediaKeySession;
|
||||||
|
|
||||||
|
typedef nsRefPtrHashtable<nsStringHashKey, MediaKeySession> KeySessionHashMap;
|
||||||
|
typedef nsRefPtrHashtable<nsUint32HashKey, dom::Promise> PromiseHashMap;
|
||||||
|
typedef nsRefPtrHashtable<nsUint32HashKey, MediaKeySession> PendingKeySessionsHashMap;
|
||||||
|
typedef uint32_t PromiseId;
|
||||||
|
|
||||||
|
// This class is used on the main thread only.
|
||||||
|
// Note: it's addref/release is not (and can't be) thread safe!
|
||||||
|
class MediaKeys MOZ_FINAL : public nsISupports,
|
||||||
|
public nsWrapperCache
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||||
|
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(MediaKeys)
|
||||||
|
|
||||||
|
MediaKeys(nsPIDOMWindow* aParentWindow, const nsAString& aKeySystem);
|
||||||
|
|
||||||
|
~MediaKeys();
|
||||||
|
|
||||||
|
nsPIDOMWindow* GetParentObject() const;
|
||||||
|
|
||||||
|
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
// Javascript: readonly attribute DOMString keySystem;
|
||||||
|
void GetKeySystem(nsString& retval) const;
|
||||||
|
|
||||||
|
// JavaScript: MediaKeys.createSession()
|
||||||
|
already_AddRefed<Promise> CreateSession(const nsAString& aInitDataType,
|
||||||
|
const Uint8Array& aInitData,
|
||||||
|
SessionType aSessionType);
|
||||||
|
|
||||||
|
// JavaScript: MediaKeys.loadSession()
|
||||||
|
already_AddRefed<Promise> LoadSession(const nsAString& aSessionId);
|
||||||
|
|
||||||
|
// JavaScript: MediaKeys.SetServerCertificate()
|
||||||
|
already_AddRefed<Promise> SetServerCertificate(const Uint8Array& aServerCertificate);
|
||||||
|
|
||||||
|
// JavaScript: MediaKeys.create()
|
||||||
|
static
|
||||||
|
already_AddRefed<Promise> Create(const GlobalObject& aGlobal,
|
||||||
|
const nsAString& aKeySystem,
|
||||||
|
ErrorResult& aRv);
|
||||||
|
|
||||||
|
// JavaScript: MediaKeys.IsTypeSupported()
|
||||||
|
static IsTypeSupportedResult IsTypeSupported(const GlobalObject& aGlobal,
|
||||||
|
const nsAString& aKeySystem,
|
||||||
|
const Optional<nsAString>& aInitDataType,
|
||||||
|
const Optional<nsAString>& aContentType,
|
||||||
|
const Optional<nsAString>& aCapability);
|
||||||
|
|
||||||
|
already_AddRefed<MediaKeySession> GetSession(const nsAString& aSessionId);
|
||||||
|
|
||||||
|
// Called once a Create() operation succeeds.
|
||||||
|
void OnCDMCreated(PromiseId aId);
|
||||||
|
// Called once a CreateSession or LoadSession succeeds.
|
||||||
|
void OnSessionActivated(PromiseId aId, const nsAString& aSessionId);
|
||||||
|
// Called once a session has closed.
|
||||||
|
void OnSessionClosed(MediaKeySession* aSession);
|
||||||
|
|
||||||
|
CDMProxy* GetCDMProxy() { return mProxy; }
|
||||||
|
|
||||||
|
// Makes a new promise, or nullptr on failure.
|
||||||
|
already_AddRefed<Promise> MakePromise();
|
||||||
|
// Stores promise in mPromises, returning an ID that can be used to retrieve
|
||||||
|
// it later. The ID is passed to the CDM, so that it can signal specific
|
||||||
|
// promises to be resolved.
|
||||||
|
PromiseId StorePromise(Promise* aPromise);
|
||||||
|
|
||||||
|
// Reject promise with DOMException corresponding to aExceptionCode.
|
||||||
|
void RejectPromise(PromiseId aId, nsresult aExceptionCode);
|
||||||
|
// Resolves promise with "undefined".
|
||||||
|
void ResolvePromise(PromiseId aId);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// Removes promise from mPromises, and returns it.
|
||||||
|
already_AddRefed<Promise> RetrievePromise(PromiseId aId);
|
||||||
|
|
||||||
|
// Owning ref to proxy. The proxy has a weak reference back to the MediaKeys,
|
||||||
|
// and the MediaKeys destructor clears the proxy's reference to the MediaKeys.
|
||||||
|
nsRefPtr<CDMProxy> mProxy;
|
||||||
|
|
||||||
|
nsCOMPtr<nsPIDOMWindow> mParent;
|
||||||
|
nsString mKeySystem;
|
||||||
|
KeySessionHashMap mKeySessions;
|
||||||
|
PromiseHashMap mPromises;
|
||||||
|
PendingKeySessionsHashMap mPendingSessions;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
|
#endif // mozilla_dom_mediakeys_h__
|
|
@ -0,0 +1,31 @@
|
||||||
|
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||||
|
# vim: set filetype=python:
|
||||||
|
# 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/.
|
||||||
|
|
||||||
|
EXPORTS.mozilla.dom += [
|
||||||
|
'MediaKeyError.h',
|
||||||
|
'MediaKeyMessageEvent.h',
|
||||||
|
'MediaKeyNeededEvent.h',
|
||||||
|
'MediaKeys.h',
|
||||||
|
'MediaKeySession.h',
|
||||||
|
]
|
||||||
|
|
||||||
|
EXPORTS.mozilla += [
|
||||||
|
'CDMProxy.h',
|
||||||
|
]
|
||||||
|
|
||||||
|
UNIFIED_SOURCES += [
|
||||||
|
'CDMProxy.cpp',
|
||||||
|
'EMELog.cpp',
|
||||||
|
'MediaKeyError.cpp',
|
||||||
|
'MediaKeyMessageEvent.cpp',
|
||||||
|
'MediaKeyNeededEvent.cpp',
|
||||||
|
'MediaKeys.cpp',
|
||||||
|
'MediaKeySession.cpp',
|
||||||
|
]
|
||||||
|
|
||||||
|
FINAL_LIBRARY = 'gklayout'
|
||||||
|
|
||||||
|
FAIL_ON_WARNINGS = True
|
|
@ -246,6 +246,9 @@ TEST(VP8VideoTrackEncoder, FetchMetaData)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encode test
|
// Encode test
|
||||||
|
// XXX(bug 1018402): Disable this test when compiled with VS2013 because it
|
||||||
|
// crashes.
|
||||||
|
#if !defined(_MSC_VER) || _MSC_VER < 1800
|
||||||
TEST(VP8VideoTrackEncoder, FrameEncode)
|
TEST(VP8VideoTrackEncoder, FrameEncode)
|
||||||
{
|
{
|
||||||
// Initiate VP8 encoder
|
// Initiate VP8 encoder
|
||||||
|
@ -275,6 +278,7 @@ TEST(VP8VideoTrackEncoder, FrameEncode)
|
||||||
EncodedFrameContainer container;
|
EncodedFrameContainer container;
|
||||||
EXPECT_TRUE(NS_SUCCEEDED(encoder.GetEncodedTrack(container)));
|
EXPECT_TRUE(NS_SUCCEEDED(encoder.GetEncodedTrack(container)));
|
||||||
}
|
}
|
||||||
|
#endif // _MSC_VER
|
||||||
|
|
||||||
// EOS test
|
// EOS test
|
||||||
TEST(VP8VideoTrackEncoder, EncodeComplete)
|
TEST(VP8VideoTrackEncoder, EncodeComplete)
|
||||||
|
|
|
@ -50,6 +50,8 @@ if CONFIG['MOZ_OMX_DECODER']:
|
||||||
|
|
||||||
PARALLEL_DIRS += ['webspeech']
|
PARALLEL_DIRS += ['webspeech']
|
||||||
|
|
||||||
|
PARALLEL_DIRS += ['eme']
|
||||||
|
|
||||||
TEST_DIRS += [
|
TEST_DIRS += [
|
||||||
'test',
|
'test',
|
||||||
'gtest',
|
'gtest',
|
||||||
|
|
|
@ -300,25 +300,20 @@ support-files =
|
||||||
[test_audio1.html]
|
[test_audio1.html]
|
||||||
[test_audio2.html]
|
[test_audio2.html]
|
||||||
[test_audioDocumentTitle.html]
|
[test_audioDocumentTitle.html]
|
||||||
skip-if = true # bug 475110
|
skip-if = true # bug 475110 - disabled since we don't play Wave files standalone
|
||||||
[test_autoplay.html]
|
[test_autoplay.html]
|
||||||
[test_autoplay_contentEditable.html]
|
[test_autoplay_contentEditable.html]
|
||||||
skip-if = buildapp == 'b2g' # bug 899074 - timeouts
|
|
||||||
[test_buffered.html]
|
[test_buffered.html]
|
||||||
skip-if = toolkit == 'android' || os == "win" || (toolkit == 'gonk' && !debug) # See bug 832768 and 864682, b2g(assertion failures)
|
|
||||||
[test_bug448534.html]
|
[test_bug448534.html]
|
||||||
skip-if = buildapp == 'b2g' # b2g(Timed out, bug 894922? Bug 902677 is for the timing out of a lot of media tests)
|
skip-if = os == 'win' # bug 894922
|
||||||
[test_bug463162.xhtml]
|
[test_bug463162.xhtml]
|
||||||
[test_bug465498.html]
|
[test_bug465498.html]
|
||||||
skip-if = os == "win" || (toolkit == 'gonk' && !debug) # See bug 832768 and 864682
|
|
||||||
[test_bug493187.html]
|
[test_bug493187.html]
|
||||||
skip-if = os == "win" || (toolkit == 'gonk' && !debug) # See bug 707777
|
|
||||||
[test_bug495145.html]
|
[test_bug495145.html]
|
||||||
[test_bug495300.html]
|
[test_bug495300.html]
|
||||||
[test_bug654550.html]
|
[test_bug654550.html]
|
||||||
[test_bug686942.html]
|
[test_bug686942.html]
|
||||||
[test_bug726904.html]
|
[test_bug726904.html]
|
||||||
skip-if = true # bug 754860
|
|
||||||
[test_bug874897.html]
|
[test_bug874897.html]
|
||||||
[test_bug883173.html]
|
[test_bug883173.html]
|
||||||
[test_bug895091.html]
|
[test_bug895091.html]
|
||||||
|
@ -327,12 +322,11 @@ skip-if = true # bug 754860
|
||||||
[test_bug957847.html]
|
[test_bug957847.html]
|
||||||
[test_can_play_type.html]
|
[test_can_play_type.html]
|
||||||
[test_can_play_type_mpeg.html]
|
[test_can_play_type_mpeg.html]
|
||||||
skip-if = buildapp == 'b2g' # b2g(7 failures out of 27)
|
skip-if = buildapp == 'b2g' # bug 1021675
|
||||||
[test_can_play_type_no_ogg.html]
|
[test_can_play_type_no_ogg.html]
|
||||||
[test_can_play_type_ogg.html]
|
[test_can_play_type_ogg.html]
|
||||||
skip-if = buildapp == 'b2g' || e10s
|
skip-if = buildapp == 'b2g' || e10s # b2g(bug 1021675)
|
||||||
[test_chaining.html]
|
[test_chaining.html]
|
||||||
skip-if = buildapp == 'b2g' # timeouts
|
|
||||||
[test_clone_media_element.html]
|
[test_clone_media_element.html]
|
||||||
[test_closing_connections.html]
|
[test_closing_connections.html]
|
||||||
[test_constants.html]
|
[test_constants.html]
|
||||||
|
@ -349,13 +343,11 @@ skip-if = buildapp == 'b2g' # timeouts
|
||||||
[test_decoder_disable.html]
|
[test_decoder_disable.html]
|
||||||
[test_defaultMuted.html]
|
[test_defaultMuted.html]
|
||||||
[test_delay_load.html]
|
[test_delay_load.html]
|
||||||
skip-if = buildapp == 'b2g' # b2g(6 failures)
|
skip-if = buildapp == 'b2g' # bug 1021676
|
||||||
[test_error_in_video_document.html]
|
[test_error_in_video_document.html]
|
||||||
skip-if = true # bug 608634
|
|
||||||
[test_error_on_404.html]
|
[test_error_on_404.html]
|
||||||
[test_fastSeek.html]
|
[test_fastSeek.html]
|
||||||
[test_info_leak.html]
|
[test_info_leak.html]
|
||||||
skip-if = buildapp == 'b2g' # b2g(2 failures)
|
|
||||||
[test_invalid_reject.html]
|
[test_invalid_reject.html]
|
||||||
[test_load.html]
|
[test_load.html]
|
||||||
[test_load_candidates.html]
|
[test_load_candidates.html]
|
||||||
|
@ -363,18 +355,18 @@ skip-if = buildapp == 'b2g' # b2g(2 failures)
|
||||||
[test_load_source.html]
|
[test_load_source.html]
|
||||||
[test_loop.html]
|
[test_loop.html]
|
||||||
[test_media_selection.html]
|
[test_media_selection.html]
|
||||||
skip-if = os == "win" || (toolkit == 'gonk' && !debug) # See bug 897843, b2g(timed out)
|
skip-if = toolkit == 'gonk' && !debug # bug 1021677
|
||||||
[test_media_sniffer.html]
|
[test_media_sniffer.html]
|
||||||
[test_mediarecorder_avoid_recursion.html]
|
[test_mediarecorder_avoid_recursion.html]
|
||||||
[test_mediarecorder_creation.html]
|
[test_mediarecorder_creation.html]
|
||||||
[test_mediarecorder_creation_fail.html]
|
[test_mediarecorder_creation_fail.html]
|
||||||
[test_mediarecorder_getencodeddata.html]
|
[test_mediarecorder_getencodeddata.html]
|
||||||
[test_mediarecorder_record_4ch_audiocontext.html]
|
[test_mediarecorder_record_4ch_audiocontext.html]
|
||||||
skip-if = (toolkit == 'gonk' && !debug)
|
skip-if = toolkit == 'gonk' && !debug # bug 1021678
|
||||||
[test_mediarecorder_record_audiocontext.html]
|
[test_mediarecorder_record_audiocontext.html]
|
||||||
[test_mediarecorder_record_audiocontext_mlk.html]
|
[test_mediarecorder_record_audiocontext_mlk.html]
|
||||||
[test_mediarecorder_record_gum_video_timeslice.html]
|
[test_mediarecorder_record_gum_video_timeslice.html]
|
||||||
skip-if = buildapp == 'b2g' || (toolkit == 'android') # mimetype check, bug 969289
|
skip-if = buildapp == 'b2g' || toolkit == 'android' # mimetype check, bug 969289
|
||||||
[test_mediarecorder_record_immediate_stop.html]
|
[test_mediarecorder_record_immediate_stop.html]
|
||||||
[test_mediarecorder_record_no_timeslice.html]
|
[test_mediarecorder_record_no_timeslice.html]
|
||||||
[test_mediarecorder_record_nosrc.html]
|
[test_mediarecorder_record_nosrc.html]
|
||||||
|
@ -386,7 +378,7 @@ skip-if = buildapp == 'b2g' || (toolkit == 'android') # mimetype check, bug 9692
|
||||||
[test_mediarecorder_unsupported_src.html]
|
[test_mediarecorder_unsupported_src.html]
|
||||||
[test_metadata.html]
|
[test_metadata.html]
|
||||||
[test_mixed_principals.html]
|
[test_mixed_principals.html]
|
||||||
skip-if = true # bug 567954 and 574586
|
skip-if = (os == 'linux' && debug) || (toolkit == 'android' && debug) || toolkit == 'gonk' # bug 567954 and intermittent leaks
|
||||||
[test_mozHasAudio.html]
|
[test_mozHasAudio.html]
|
||||||
[test_networkState.html]
|
[test_networkState.html]
|
||||||
[test_new_audio.html]
|
[test_new_audio.html]
|
||||||
|
@ -402,13 +394,14 @@ skip-if = appname == "seamonkey" || toolkit == 'gonk' || toolkit == 'android'
|
||||||
skip-if = buildapp == 'b2g' || toolkit == 'android' # Disabled on Android & B2G due to bug 668973
|
skip-if = buildapp == 'b2g' || toolkit == 'android' # Disabled on Android & B2G due to bug 668973
|
||||||
[test_playback_errors.html]
|
[test_playback_errors.html]
|
||||||
[test_playback_rate.html]
|
[test_playback_rate.html]
|
||||||
# Win: Bug 814533, B2G & Android Debug: Bug 1020538
|
# Win: Bug 814533, B2G & Android Debug: Bug 1020538, see assertion annotations in test also
|
||||||
skip-if = os == 'win' || buildapp == 'b2g' || (toolkit == 'android' && debug)
|
skip-if = os == 'win' || buildapp == 'b2g' || (toolkit == 'android' && debug)
|
||||||
[test_playback_rate_playpause.html]
|
[test_playback_rate_playpause.html]
|
||||||
skip-if = true # bug 897108
|
skip-if = os == 'linux' || os == 'win' # bug 897108, see assertion annotations in test also
|
||||||
[test_played.html]
|
[test_played.html]
|
||||||
skip-if = true # bug 751539
|
skip-if = true # bug 1021794
|
||||||
[test_preload_actions.html]
|
[test_preload_actions.html]
|
||||||
|
skip-if = toolkit == 'android' # bug 886188
|
||||||
[test_preload_attribute.html]
|
[test_preload_attribute.html]
|
||||||
[test_preload_suspend.html]
|
[test_preload_suspend.html]
|
||||||
skip-if = true # bug 493692
|
skip-if = true # bug 493692
|
||||||
|
@ -420,15 +413,13 @@ skip-if = true # bug 493692
|
||||||
[test_reset_events_async.html]
|
[test_reset_events_async.html]
|
||||||
[test_reset_src.html]
|
[test_reset_src.html]
|
||||||
[test_resume.html]
|
[test_resume.html]
|
||||||
skip-if = true # disabled - No bug :-(
|
skip-if = true # bug 1021673
|
||||||
[test_seek_out_of_range.html]
|
[test_seek_out_of_range.html]
|
||||||
[test_seek.html]
|
[test_seek.html]
|
||||||
skip-if = toolkit == 'android' || (toolkit == 'gonk' && !debug) # See bug 832678, 795271, and 857424 # android(bug 845162) androidx86(bug 845162)
|
|
||||||
[test_seek2.html]
|
[test_seek2.html]
|
||||||
[test_seekable1.html]
|
[test_seekable1.html]
|
||||||
[test_seekable2.html]
|
[test_seekable2.html]
|
||||||
[test_seekable3.html]
|
[test_seekable3.html]
|
||||||
skip-if = buildapp == 'b2g' # timeouts
|
|
||||||
[test_seekLies.html]
|
[test_seekLies.html]
|
||||||
[test_source.html]
|
[test_source.html]
|
||||||
[test_source_media.html]
|
[test_source_media.html]
|
||||||
|
@ -442,7 +433,7 @@ skip-if = buildapp == 'b2g' # timeouts
|
||||||
[test_streams_element_capture_reset.html]
|
[test_streams_element_capture_reset.html]
|
||||||
skip-if = buildapp == 'b2g' # bug 901102
|
skip-if = buildapp == 'b2g' # bug 901102
|
||||||
[test_streams_gc.html]
|
[test_streams_gc.html]
|
||||||
skip-if = buildapp == 'b2g' # Value being assigned to HTMLMediaElement.currentTime is not a finite floating-point value
|
skip-if = buildapp == 'b2g' # bug 1021682
|
||||||
[test_streams_srcObject.html]
|
[test_streams_srcObject.html]
|
||||||
[test_streams_tracks.html]
|
[test_streams_tracks.html]
|
||||||
[test_texttrack.html]
|
[test_texttrack.html]
|
||||||
|
@ -453,10 +444,8 @@ skip-if = buildapp == 'b2g' # Value being assigned to HTMLMediaElement.currentTi
|
||||||
[test_trackelementevent.html]
|
[test_trackelementevent.html]
|
||||||
[test_trackevent.html]
|
[test_trackevent.html]
|
||||||
[test_unseekable.html]
|
[test_unseekable.html]
|
||||||
skip-if = buildapp == 'b2g'
|
|
||||||
[test_video_to_canvas.html]
|
[test_video_to_canvas.html]
|
||||||
[test_videoDocumentTitle.html]
|
[test_videoDocumentTitle.html]
|
||||||
skip-if = true # bug 492821
|
|
||||||
[test_VideoPlaybackQuality.html]
|
[test_VideoPlaybackQuality.html]
|
||||||
[test_VideoPlaybackQuality_disabled.html]
|
[test_VideoPlaybackQuality_disabled.html]
|
||||||
[test_volume.html]
|
[test_volume.html]
|
||||||
|
|
|
@ -21,8 +21,6 @@
|
||||||
SimpleTest.expectAssertions(5, 9);
|
SimpleTest.expectAssertions(5, 9);
|
||||||
if (navigator.platform.startsWith("Win")) {
|
if (navigator.platform.startsWith("Win")) {
|
||||||
SimpleTest.expectAssertions(4, 5);
|
SimpleTest.expectAssertions(4, 5);
|
||||||
} else if (navigator.platform.startsWith("Mac")) {
|
|
||||||
SimpleTest.expectAssertions(5, 7);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let manager = new MediaTestManager;
|
let manager = new MediaTestManager;
|
||||||
|
|
|
@ -10,13 +10,16 @@
|
||||||
<pre id="test">
|
<pre id="test">
|
||||||
<script class="testbody" type='application/javascript;version=1.8'>
|
<script class="testbody" type='application/javascript;version=1.8'>
|
||||||
|
|
||||||
|
// In varying quantities:
|
||||||
|
// ASSERTION: Clock should go forwards if the playback rate is > 0.:
|
||||||
|
// 'mCurrentFrameTime <= clock_time || mPlaybackRate <= 0',
|
||||||
|
// file MediaDecoderStateMachine.cpp, line 2379
|
||||||
if (navigator.platform.startsWith("Win")) {
|
if (navigator.platform.startsWith("Win")) {
|
||||||
SimpleTest.expectAssertions(0, 1);
|
SimpleTest.expectAssertions(1, 6);
|
||||||
} else if (navigator.platform.startsWith("Mac")) {
|
} else if (navigator.platform.startsWith("Mac")) {
|
||||||
SimpleTest.expectAssertions(0, 2);
|
SimpleTest.expectAssertions(3, 7);
|
||||||
} else if (navigator.platform.startsWith("Linux")) {
|
} else if (navigator.platform.startsWith("Linux arm")) {
|
||||||
// Bug 897024
|
SimpleTest.expectAssertions(4, 11);
|
||||||
SimpleTest.expectAssertions(0, 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let manager = new MediaTestManager;
|
let manager = new MediaTestManager;
|
||||||
|
|
|
@ -43,7 +43,7 @@ private:
|
||||||
uint32_t mChunkSize;
|
uint32_t mChunkSize;
|
||||||
|
|
||||||
// chunking to 10ms support
|
// chunking to 10ms support
|
||||||
nsAutoPtr<FarEndAudioChunk> mSaved;
|
FarEndAudioChunk *mSaved; // can't be nsAutoPtr since we need to use moz_free()
|
||||||
uint32_t mSamplesSaved;
|
uint32_t mSamplesSaved;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,7 @@ AudioOutputObserver::AudioOutputObserver()
|
||||||
: mPlayoutFreq(0)
|
: mPlayoutFreq(0)
|
||||||
, mPlayoutChannels(0)
|
, mPlayoutChannels(0)
|
||||||
, mChunkSize(0)
|
, mChunkSize(0)
|
||||||
|
, mSaved(nullptr)
|
||||||
, mSamplesSaved(0)
|
, mSamplesSaved(0)
|
||||||
{
|
{
|
||||||
// Buffers of 10ms chunks
|
// Buffers of 10ms chunks
|
||||||
|
@ -69,8 +70,9 @@ void
|
||||||
AudioOutputObserver::Clear()
|
AudioOutputObserver::Clear()
|
||||||
{
|
{
|
||||||
while (mPlayoutFifo->size() > 0) {
|
while (mPlayoutFifo->size() > 0) {
|
||||||
(void) mPlayoutFifo->Pop();
|
moz_free(mPlayoutFifo->Pop());
|
||||||
}
|
}
|
||||||
|
moz_free(mSaved);
|
||||||
mSaved = nullptr;
|
mSaved = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,7 +156,8 @@ AudioOutputObserver::InsertFarEnd(const AudioDataValue *aBuffer, uint32_t aSampl
|
||||||
// thread safety issues.
|
// thread safety issues.
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
mPlayoutFifo->Push((int8_t *) mSaved.forget()); // takes ownership
|
mPlayoutFifo->Push((int8_t *) mSaved); // takes ownership
|
||||||
|
mSaved = nullptr;
|
||||||
mSamplesSaved = 0;
|
mSamplesSaved = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -517,8 +520,7 @@ MediaEngineWebRTCAudioSource::Process(int channel,
|
||||||
if (!mStarted) {
|
if (!mStarted) {
|
||||||
mStarted = true;
|
mStarted = true;
|
||||||
while (gFarendObserver->Size() > 1) {
|
while (gFarendObserver->Size() > 1) {
|
||||||
FarEndAudioChunk *buffer = gFarendObserver->Pop(); // only call if size() > 0
|
moz_free(gFarendObserver->Pop()); // only call if size() > 0
|
||||||
free(buffer);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -526,15 +528,16 @@ MediaEngineWebRTCAudioSource::Process(int channel,
|
||||||
FarEndAudioChunk *buffer = gFarendObserver->Pop(); // only call if size() > 0
|
FarEndAudioChunk *buffer = gFarendObserver->Pop(); // only call if size() > 0
|
||||||
if (buffer) {
|
if (buffer) {
|
||||||
int length = buffer->mSamples;
|
int length = buffer->mSamples;
|
||||||
if (mVoERender->ExternalPlayoutData(buffer->mData,
|
int res = mVoERender->ExternalPlayoutData(buffer->mData,
|
||||||
gFarendObserver->PlayoutFrequency(),
|
gFarendObserver->PlayoutFrequency(),
|
||||||
gFarendObserver->PlayoutChannels(),
|
gFarendObserver->PlayoutChannels(),
|
||||||
mPlayoutDelay,
|
mPlayoutDelay,
|
||||||
length) == -1) {
|
length);
|
||||||
|
moz_free(buffer);
|
||||||
|
if (res == -1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(buffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef PR_LOGGING
|
#ifdef PR_LOGGING
|
||||||
|
|
|
@ -83,3 +83,4 @@ skip-if = toolkit == "gtk2"
|
||||||
[test_principalInherit.xul]
|
[test_principalInherit.xul]
|
||||||
[test_private_hidden_window.html]
|
[test_private_hidden_window.html]
|
||||||
[test_viewsource_forbidden_in_iframe.xul]
|
[test_viewsource_forbidden_in_iframe.xul]
|
||||||
|
skip-if = true # bug 1019315
|
||||||
|
|
|
@ -163,7 +163,7 @@ this.PermissionsTable = { geolocation: {
|
||||||
},
|
},
|
||||||
attention: {
|
attention: {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
privileged: DENY_ACTION,
|
privileged: ALLOW_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"webapps-manage": {
|
"webapps-manage": {
|
||||||
|
@ -298,7 +298,7 @@ this.PermissionsTable = { geolocation: {
|
||||||
"audio-capture": {
|
"audio-capture": {
|
||||||
app: PROMPT_ACTION,
|
app: PROMPT_ACTION,
|
||||||
privileged: PROMPT_ACTION,
|
privileged: PROMPT_ACTION,
|
||||||
certified: PROMPT_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"nfc": {
|
"nfc": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
|
@ -324,7 +324,7 @@ this.PermissionsTable = { geolocation: {
|
||||||
"video-capture": {
|
"video-capture": {
|
||||||
app: PROMPT_ACTION,
|
app: PROMPT_ACTION,
|
||||||
privileged: PROMPT_ACTION,
|
privileged: PROMPT_ACTION,
|
||||||
certified: PROMPT_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"feature-detection": {
|
"feature-detection": {
|
||||||
app: DENY_ACTION,
|
app: DENY_ACTION,
|
||||||
|
|
|
@ -948,9 +948,12 @@ this.DOMApplicationRegistry = {
|
||||||
delete this.webapps[aResult.id];
|
delete this.webapps[aResult.id];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
app.name = manifest.name;
|
|
||||||
|
let localeManifest = new ManifestHelper(manifest, app.origin);
|
||||||
|
|
||||||
|
app.name = localeManifest.name;
|
||||||
app.csp = manifest.csp || "";
|
app.csp = manifest.csp || "";
|
||||||
app.role = manifest.role || "";
|
app.role = localeManifest.role;
|
||||||
if (app.appStatus >= Ci.nsIPrincipal.APP_STATUS_PRIVILEGED) {
|
if (app.appStatus >= Ci.nsIPrincipal.APP_STATUS_PRIVILEGED) {
|
||||||
app.redirects = this.sanitizeRedirects(manifest.redirects);
|
app.redirects = this.sanitizeRedirects(manifest.redirects);
|
||||||
}
|
}
|
||||||
|
@ -1333,12 +1336,12 @@ this.DOMApplicationRegistry = {
|
||||||
let app = this.webapps[id];
|
let app = this.webapps[id];
|
||||||
if (!app) {
|
if (!app) {
|
||||||
debug("startDownload: No app found for " + aManifestURL);
|
debug("startDownload: No app found for " + aManifestURL);
|
||||||
return;
|
throw new Error("NO_SUCH_APP");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (app.downloading) {
|
if (app.downloading) {
|
||||||
debug("app is already downloading. Ignoring.");
|
debug("app is already downloading. Ignoring.");
|
||||||
return;
|
throw new Error("APP_IS_DOWNLOADING");
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the caller is trying to start a download but we have nothing to
|
// If the caller is trying to start a download but we have nothing to
|
||||||
|
@ -1352,7 +1355,7 @@ this.DOMApplicationRegistry = {
|
||||||
eventType: "downloaderror",
|
eventType: "downloaderror",
|
||||||
manifestURL: app.manifestURL
|
manifestURL: app.manifestURL
|
||||||
});
|
});
|
||||||
return;
|
throw new Error("NO_DOWNLOAD_AVAILABLE");
|
||||||
}
|
}
|
||||||
|
|
||||||
// First of all, we check if the download is supposed to update an
|
// First of all, we check if the download is supposed to update an
|
||||||
|
@ -1409,7 +1412,7 @@ this.DOMApplicationRegistry = {
|
||||||
if (!json) {
|
if (!json) {
|
||||||
debug("startDownload: No update manifest found at " + file.path + " " +
|
debug("startDownload: No update manifest found at " + file.path + " " +
|
||||||
aManifestURL);
|
aManifestURL);
|
||||||
return;
|
throw new Error("MISSING_UPDATE_MANIFEST");
|
||||||
}
|
}
|
||||||
|
|
||||||
let manifest = new ManifestHelper(json, app.manifestURL);
|
let manifest = new ManifestHelper(json, app.manifestURL);
|
||||||
|
@ -1450,104 +1453,103 @@ this.DOMApplicationRegistry = {
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
applyDownload: function applyDownload(aManifestURL) {
|
applyDownload: Task.async(function*(aManifestURL) {
|
||||||
debug("applyDownload for " + aManifestURL);
|
debug("applyDownload for " + aManifestURL);
|
||||||
let id = this._appIdForManifestURL(aManifestURL);
|
let id = this._appIdForManifestURL(aManifestURL);
|
||||||
let app = this.webapps[id];
|
let app = this.webapps[id];
|
||||||
if (!app || (app && !app.readyToApplyDownload)) {
|
if (!app) {
|
||||||
return;
|
throw new Error("NO_SUCH_APP");
|
||||||
|
}
|
||||||
|
if (!app.readyToApplyDownload) {
|
||||||
|
throw new Error("NOT_READY_TO_APPLY_DOWNLOAD");
|
||||||
}
|
}
|
||||||
|
|
||||||
// We need to get the old manifest to unregister web activities.
|
// We need to get the old manifest to unregister web activities.
|
||||||
this.getManifestFor(aManifestURL).then((aOldManifest) => {
|
let oldManifest = yield this.getManifestFor(aManifestURL);
|
||||||
// Move the application.zip and manifest.webapp files out of TmpD
|
// Move the application.zip and manifest.webapp files out of TmpD
|
||||||
let tmpDir = FileUtils.getDir("TmpD", ["webapps", id], true, true);
|
let tmpDir = FileUtils.getDir("TmpD", ["webapps", id], true, true);
|
||||||
let manFile = tmpDir.clone();
|
let manFile = tmpDir.clone();
|
||||||
manFile.append("manifest.webapp");
|
manFile.append("manifest.webapp");
|
||||||
let appFile = tmpDir.clone();
|
let appFile = tmpDir.clone();
|
||||||
appFile.append("application.zip");
|
appFile.append("application.zip");
|
||||||
|
|
||||||
let dir = FileUtils.getDir(DIRECTORY_NAME, ["webapps", id], true, true);
|
let dir = FileUtils.getDir(DIRECTORY_NAME, ["webapps", id], true, true);
|
||||||
appFile.moveTo(dir, "application.zip");
|
appFile.moveTo(dir, "application.zip");
|
||||||
manFile.moveTo(dir, "manifest.webapp");
|
manFile.moveTo(dir, "manifest.webapp");
|
||||||
|
|
||||||
// Move the staged update manifest to a non staged one.
|
// Move the staged update manifest to a non staged one.
|
||||||
let staged = dir.clone();
|
let staged = dir.clone();
|
||||||
staged.append("staged-update.webapp");
|
staged.append("staged-update.webapp");
|
||||||
|
|
||||||
// If we are applying after a restarted download, we have no
|
// If we are applying after a restarted download, we have no
|
||||||
// staged update manifest.
|
// staged update manifest.
|
||||||
if (staged.exists()) {
|
if (staged.exists()) {
|
||||||
staged.moveTo(dir, "update.webapp");
|
staged.moveTo(dir, "update.webapp");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
tmpDir.remove(true);
|
||||||
|
} catch(e) { }
|
||||||
|
|
||||||
|
// Clean up the deprecated manifest cache if needed.
|
||||||
|
if (id in this._manifestCache) {
|
||||||
|
delete this._manifestCache[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flush the zip reader cache to make sure we use the new application.zip
|
||||||
|
// when re-launching the application.
|
||||||
|
let zipFile = dir.clone();
|
||||||
|
zipFile.append("application.zip");
|
||||||
|
Services.obs.notifyObservers(zipFile, "flush-cache-entry", null);
|
||||||
|
|
||||||
|
// Get the manifest, and set properties.
|
||||||
|
let newManifest = yield this.getManifestFor(aManifestURL);
|
||||||
|
app.downloading = false;
|
||||||
|
app.downloadAvailable = false;
|
||||||
|
app.downloadSize = 0;
|
||||||
|
app.installState = "installed";
|
||||||
|
app.readyToApplyDownload = false;
|
||||||
|
|
||||||
|
// Update the staged properties.
|
||||||
|
if (app.staged) {
|
||||||
|
for (let prop in app.staged) {
|
||||||
|
app[prop] = app.staged[prop];
|
||||||
}
|
}
|
||||||
|
delete app.staged;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
delete app.retryingDownload;
|
||||||
tmpDir.remove(true);
|
|
||||||
} catch(e) { }
|
|
||||||
|
|
||||||
// Clean up the deprecated manifest cache if needed.
|
// Update the asm.js scripts we need to compile.
|
||||||
if (id in this._manifestCache) {
|
yield ScriptPreloader.preload(app, newManifest);
|
||||||
delete this._manifestCache[id];
|
yield this._saveApps();
|
||||||
}
|
// Update the handlers and permissions for this app.
|
||||||
|
this.updateAppHandlers(oldManifest, newManifest, app);
|
||||||
|
|
||||||
// Flush the zip reader cache to make sure we use the new application.zip
|
let updateManifest = yield AppsUtils.loadJSONAsync(staged.path);
|
||||||
// when re-launching the application.
|
let appObject = AppsUtils.cloneAppObject(app);
|
||||||
let zipFile = dir.clone();
|
appObject.updateManifest = updateManifest;
|
||||||
zipFile.append("application.zip");
|
this.notifyUpdateHandlers(appObject, newManifest, appFile.path);
|
||||||
Services.obs.notifyObservers(zipFile, "flush-cache-entry", null);
|
|
||||||
|
|
||||||
// Get the manifest, and set properties.
|
if (supportUseCurrentProfile()) {
|
||||||
this.getManifestFor(aManifestURL).then((aData) => {
|
PermissionsInstaller.installPermissions(
|
||||||
app.downloading = false;
|
{ manifest: newManifest,
|
||||||
app.downloadAvailable = false;
|
origin: app.origin,
|
||||||
app.downloadSize = 0;
|
manifestURL: app.manifestURL },
|
||||||
app.installState = "installed";
|
true);
|
||||||
app.readyToApplyDownload = false;
|
}
|
||||||
|
this.updateDataStore(this.webapps[id].localId, app.origin,
|
||||||
// Update the staged properties.
|
app.manifestURL, newManifest, app.appStatus);
|
||||||
if (app.staged) {
|
this.broadcastMessage("Webapps:UpdateState", {
|
||||||
for (let prop in app.staged) {
|
app: app,
|
||||||
app[prop] = app.staged[prop];
|
manifest: newManifest,
|
||||||
}
|
manifestURL: app.manifestURL
|
||||||
delete app.staged;
|
|
||||||
}
|
|
||||||
|
|
||||||
delete app.retryingDownload;
|
|
||||||
|
|
||||||
// Update the asm.js scripts we need to compile.
|
|
||||||
ScriptPreloader.preload(app, aData)
|
|
||||||
.then(() => this._saveApps()).then(() => {
|
|
||||||
// Update the handlers and permissions for this app.
|
|
||||||
this.updateAppHandlers(aOldManifest, aData, app);
|
|
||||||
|
|
||||||
AppsUtils.loadJSONAsync(staged.path).then((aUpdateManifest) => {
|
|
||||||
let appObject = AppsUtils.cloneAppObject(app);
|
|
||||||
appObject.updateManifest = aUpdateManifest;
|
|
||||||
this.notifyUpdateHandlers(appObject, aData, appFile.path);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (supportUseCurrentProfile()) {
|
|
||||||
PermissionsInstaller.installPermissions(
|
|
||||||
{ manifest: aData,
|
|
||||||
origin: app.origin,
|
|
||||||
manifestURL: app.manifestURL },
|
|
||||||
true);
|
|
||||||
}
|
|
||||||
this.updateDataStore(this.webapps[id].localId, app.origin,
|
|
||||||
app.manifestURL, aData, app.appStatus);
|
|
||||||
this.broadcastMessage("Webapps:UpdateState", {
|
|
||||||
app: app,
|
|
||||||
manifest: aData,
|
|
||||||
manifestURL: app.manifestURL
|
|
||||||
});
|
|
||||||
this.broadcastMessage("Webapps:FireEvent", {
|
|
||||||
eventType: "downloadapplied",
|
|
||||||
manifestURL: app.manifestURL
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
},
|
this.broadcastMessage("Webapps:FireEvent", {
|
||||||
|
eventType: "downloadapplied",
|
||||||
|
manifestURL: app.manifestURL
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
|
||||||
startOfflineCacheDownload: function(aManifest, aApp, aProfileDir, aIsUpdate) {
|
startOfflineCacheDownload: function(aManifest, aApp, aProfileDir, aIsUpdate) {
|
||||||
if (!aManifest.appcache_path) {
|
if (!aManifest.appcache_path) {
|
||||||
|
@ -2773,9 +2775,11 @@ this.DOMApplicationRegistry = {
|
||||||
if (oldPackage) {
|
if (oldPackage) {
|
||||||
debug("package's etag or hash unchanged; sending 'applied' event");
|
debug("package's etag or hash unchanged; sending 'applied' event");
|
||||||
// The package's Etag or hash has not changed.
|
// The package's Etag or hash has not changed.
|
||||||
// We send a "applied" event right away.
|
// We send an "applied" event right away so code awaiting that event
|
||||||
|
// can proceed to access the app. We also throw an error to alert
|
||||||
|
// the caller that the package wasn't downloaded.
|
||||||
this._sendAppliedEvent(aNewApp, oldApp, id);
|
this._sendAppliedEvent(aNewApp, oldApp, id);
|
||||||
return;
|
throw new Error("PACKAGE_UNCHANGED");
|
||||||
}
|
}
|
||||||
|
|
||||||
let newManifest = yield this._openAndReadPackage(zipFile, oldApp, aNewApp,
|
let newManifest = yield this._openAndReadPackage(zipFile, oldApp, aNewApp,
|
||||||
|
@ -3488,6 +3492,8 @@ this.DOMApplicationRegistry = {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
AppDownloadManager.remove(aNewApp.manifestURL);
|
AppDownloadManager.remove(aNewApp.manifestURL);
|
||||||
|
|
||||||
|
throw aError;
|
||||||
},
|
},
|
||||||
|
|
||||||
doUninstall: function(aData, aMm) {
|
doUninstall: function(aData, aMm) {
|
||||||
|
|
|
@ -798,7 +798,7 @@ Navigator::Vibrate(const nsTArray<uint32_t>& aPattern)
|
||||||
nsTArray<uint32_t> pattern(aPattern);
|
nsTArray<uint32_t> pattern(aPattern);
|
||||||
|
|
||||||
if (pattern.Length() > sMaxVibrateListLen) {
|
if (pattern.Length() > sMaxVibrateListLen) {
|
||||||
pattern.SetLength(sMaxVibrateMS);
|
pattern.SetLength(sMaxVibrateListLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < pattern.Length(); ++i) {
|
for (size_t i = 0; i < pattern.Length(); ++i) {
|
||||||
|
|
|
@ -33,7 +33,6 @@ public:
|
||||||
{
|
{
|
||||||
switch (mHash->Mechanism()) {
|
switch (mHash->Mechanism()) {
|
||||||
case CKM_SHA_1: mMechanism = CKM_SHA_1_HMAC; break;
|
case CKM_SHA_1: mMechanism = CKM_SHA_1_HMAC; break;
|
||||||
case CKM_SHA224: mMechanism = CKM_SHA224_HMAC; break;
|
|
||||||
case CKM_SHA256: mMechanism = CKM_SHA256_HMAC; break;
|
case CKM_SHA256: mMechanism = CKM_SHA256_HMAC; break;
|
||||||
case CKM_SHA384: mMechanism = CKM_SHA384_HMAC; break;
|
case CKM_SHA384: mMechanism = CKM_SHA384_HMAC; break;
|
||||||
case CKM_SHA512: mMechanism = CKM_SHA512_HMAC; break;
|
case CKM_SHA512: mMechanism = CKM_SHA512_HMAC; break;
|
||||||
|
|
|
@ -40,8 +40,6 @@ KeyAlgorithm::KeyAlgorithm(nsIGlobalObject* aGlobal, const nsString& aName)
|
||||||
mMechanism = CKM_AES_GCM;
|
mMechanism = CKM_AES_GCM;
|
||||||
} else if (mName.EqualsLiteral(WEBCRYPTO_ALG_SHA1)) {
|
} else if (mName.EqualsLiteral(WEBCRYPTO_ALG_SHA1)) {
|
||||||
mMechanism = CKM_SHA_1;
|
mMechanism = CKM_SHA_1;
|
||||||
} else if (mName.EqualsLiteral(WEBCRYPTO_ALG_SHA224)) {
|
|
||||||
mMechanism = CKM_SHA224;
|
|
||||||
} else if (mName.EqualsLiteral(WEBCRYPTO_ALG_SHA256)) {
|
} else if (mName.EqualsLiteral(WEBCRYPTO_ALG_SHA256)) {
|
||||||
mMechanism = CKM_SHA256;
|
mMechanism = CKM_SHA256;
|
||||||
} else if (mName.EqualsLiteral(WEBCRYPTO_ALG_SHA384)) {
|
} else if (mName.EqualsLiteral(WEBCRYPTO_ALG_SHA384)) {
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
#define WEBCRYPTO_ALG_AES_GCM "AES-GCM"
|
#define WEBCRYPTO_ALG_AES_GCM "AES-GCM"
|
||||||
#define WEBCRYPTO_ALG_SHA1 "SHA-1"
|
#define WEBCRYPTO_ALG_SHA1 "SHA-1"
|
||||||
#define WEBCRYPTO_ALG_SHA256 "SHA-256"
|
#define WEBCRYPTO_ALG_SHA256 "SHA-256"
|
||||||
#define WEBCRYPTO_ALG_SHA224 "SHA-224"
|
|
||||||
#define WEBCRYPTO_ALG_SHA384 "SHA-384"
|
#define WEBCRYPTO_ALG_SHA384 "SHA-384"
|
||||||
#define WEBCRYPTO_ALG_SHA512 "SHA-512"
|
#define WEBCRYPTO_ALG_SHA512 "SHA-512"
|
||||||
#define WEBCRYPTO_ALG_HMAC "HMAC"
|
#define WEBCRYPTO_ALG_HMAC "HMAC"
|
||||||
|
|
|
@ -489,8 +489,6 @@ public:
|
||||||
switch (hashAlg->Mechanism()) {
|
switch (hashAlg->Mechanism()) {
|
||||||
case CKM_SHA_1:
|
case CKM_SHA_1:
|
||||||
mOidTag = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION; break;
|
mOidTag = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION; break;
|
||||||
case CKM_SHA224:
|
|
||||||
mOidTag = SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION; break;
|
|
||||||
case CKM_SHA256:
|
case CKM_SHA256:
|
||||||
mOidTag = SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION; break;
|
mOidTag = SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION; break;
|
||||||
case CKM_SHA384:
|
case CKM_SHA384:
|
||||||
|
@ -598,8 +596,6 @@ public:
|
||||||
|
|
||||||
if (algName.EqualsLiteral(WEBCRYPTO_ALG_SHA1)) {
|
if (algName.EqualsLiteral(WEBCRYPTO_ALG_SHA1)) {
|
||||||
mOidTag = SEC_OID_SHA1;
|
mOidTag = SEC_OID_SHA1;
|
||||||
} else if (algName.EqualsLiteral(WEBCRYPTO_ALG_SHA224)) {
|
|
||||||
mOidTag = SEC_OID_SHA224;
|
|
||||||
} else if (algName.EqualsLiteral(WEBCRYPTO_ALG_SHA256)) {
|
} else if (algName.EqualsLiteral(WEBCRYPTO_ALG_SHA256)) {
|
||||||
mOidTag = SEC_OID_SHA256;
|
mOidTag = SEC_OID_SHA256;
|
||||||
} else if (algName.EqualsLiteral(WEBCRYPTO_ALG_SHA384)) {
|
} else if (algName.EqualsLiteral(WEBCRYPTO_ALG_SHA384)) {
|
||||||
|
@ -1022,8 +1018,7 @@ public:
|
||||||
} else if (algName.EqualsLiteral(WEBCRYPTO_ALG_HMAC)) {
|
} else if (algName.EqualsLiteral(WEBCRYPTO_ALG_HMAC)) {
|
||||||
RootedDictionary<HmacKeyGenParams> params(aCx);
|
RootedDictionary<HmacKeyGenParams> params(aCx);
|
||||||
mEarlyRv = Coerce(aCx, params, aAlgorithm);
|
mEarlyRv = Coerce(aCx, params, aAlgorithm);
|
||||||
if (NS_FAILED(mEarlyRv) || !params.mLength.WasPassed() ||
|
if (NS_FAILED(mEarlyRv) || !params.mHash.WasPassed()) {
|
||||||
!params.mHash.WasPassed()) {
|
|
||||||
mEarlyRv = NS_ERROR_DOM_SYNTAX_ERR;
|
mEarlyRv = NS_ERROR_DOM_SYNTAX_ERR;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1041,7 +1036,24 @@ public:
|
||||||
hashName.Assign(hashAlg.mName.Value());
|
hashName.Assign(hashAlg.mName.Value());
|
||||||
}
|
}
|
||||||
|
|
||||||
mLength = params.mLength.Value();
|
if (params.mLength.WasPassed()) {
|
||||||
|
mLength = params.mLength.Value();
|
||||||
|
} else {
|
||||||
|
KeyAlgorithm hashAlg(global, hashName);
|
||||||
|
switch (hashAlg.Mechanism()) {
|
||||||
|
case CKM_SHA_1: mLength = 128; break;
|
||||||
|
case CKM_SHA256: mLength = 256; break;
|
||||||
|
case CKM_SHA384: mLength = 384; break;
|
||||||
|
case CKM_SHA512: mLength = 512; break;
|
||||||
|
default: mLength = 0; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mLength == 0) {
|
||||||
|
mEarlyRv = NS_ERROR_DOM_DATA_ERR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
algorithm = new HmacKeyAlgorithm(global, algName, mLength, hashName);
|
algorithm = new HmacKeyAlgorithm(global, algName, mLength, hashName);
|
||||||
allowedUsages = Key::SIGN | Key::VERIFY;
|
allowedUsages = Key::SIGN | Key::VERIFY;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -309,6 +309,62 @@ TestArray.addTest(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
TestArray.addTest(
|
||||||
|
"Generate a 256-bit HMAC-SHA-256 key",
|
||||||
|
function() {
|
||||||
|
var that = this;
|
||||||
|
var alg = { name: "HMAC", length: 256, hash: {name: "SHA-256"} };
|
||||||
|
crypto.subtle.generateKey(alg, true, ["sign", "verify"]).then(
|
||||||
|
complete(that, function(x) {
|
||||||
|
return hasKeyFields(x) && x.algorithm.length == 256;
|
||||||
|
}),
|
||||||
|
error(that)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
TestArray.addTest(
|
||||||
|
"Generate a 256-bit HMAC-SHA-256 key without specifying a key length",
|
||||||
|
function() {
|
||||||
|
var that = this;
|
||||||
|
var alg = { name: "HMAC", hash: {name: "SHA-256"} };
|
||||||
|
crypto.subtle.generateKey(alg, true, ["sign", "verify"]).then(
|
||||||
|
complete(that, function(x) {
|
||||||
|
return hasKeyFields(x) && x.algorithm.length == 256;
|
||||||
|
}),
|
||||||
|
error(that)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
TestArray.addTest(
|
||||||
|
"Fail generating an HMAC key when specifying an invalid hash algorithm",
|
||||||
|
function() {
|
||||||
|
var that = this;
|
||||||
|
var alg = { name: "HMAC", hash: {name: "SHA-123"} };
|
||||||
|
crypto.subtle.generateKey(alg, true, ["sign", "verify"]).then(
|
||||||
|
error(that),
|
||||||
|
complete(that, function() { return true; })
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
TestArray.addTest(
|
||||||
|
"Fail generating an HMAC key when specifying a zero length",
|
||||||
|
function() {
|
||||||
|
var that = this;
|
||||||
|
var alg = { name: "HMAC", hash: {name: "SHA-256"}, length: 0 };
|
||||||
|
crypto.subtle.generateKey(alg, true, ["sign", "verify"]).then(
|
||||||
|
error(that),
|
||||||
|
complete(that, function() { return true; })
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
TestArray.addTest(
|
TestArray.addTest(
|
||||||
"Generate a 192-bit AES key",
|
"Generate a 192-bit AES key",
|
||||||
|
|
|
@ -293,7 +293,6 @@ EVENT(mozpointerlockerror,
|
||||||
NS_POINTERLOCKERROR,
|
NS_POINTERLOCKERROR,
|
||||||
EventNameType_HTML,
|
EventNameType_HTML,
|
||||||
NS_EVENT)
|
NS_EVENT)
|
||||||
|
|
||||||
EVENT(pointerdown,
|
EVENT(pointerdown,
|
||||||
NS_POINTER_DOWN,
|
NS_POINTER_DOWN,
|
||||||
EventNameType_All,
|
EventNameType_All,
|
||||||
|
|
|
@ -1440,7 +1440,7 @@ EventStateManager::FireContextClick()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nsIDocument* doc = mGestureDownContent->GetCurrentDoc();
|
nsIDocument* doc = mGestureDownContent->GetCrossShadowCurrentDoc();
|
||||||
AutoHandlingUserInputStatePusher userInpStatePusher(true, &event, doc);
|
AutoHandlingUserInputStatePusher userInpStatePusher(true, &event, doc);
|
||||||
|
|
||||||
// dispatch to DOM
|
// dispatch to DOM
|
||||||
|
@ -2011,7 +2011,7 @@ EventStateManager::DoScrollZoom(nsIFrame* aTargetFrame,
|
||||||
// positive adjustment to decrease zoom, negative to increase
|
// positive adjustment to decrease zoom, negative to increase
|
||||||
int32_t change = (adjustment > 0) ? -1 : 1;
|
int32_t change = (adjustment > 0) ? -1 : 1;
|
||||||
|
|
||||||
if (Preferences::GetBool("browser.zoom.full") || content->GetCurrentDoc()->IsSyntheticDocument()) {
|
if (Preferences::GetBool("browser.zoom.full") || content->OwnerDoc()->IsSyntheticDocument()) {
|
||||||
ChangeFullZoom(change);
|
ChangeFullZoom(change);
|
||||||
} else {
|
} else {
|
||||||
ChangeTextSize(change);
|
ChangeTextSize(change);
|
||||||
|
@ -2752,7 +2752,7 @@ EventStateManager::PostHandleEvent(nsPresContext* aPresContext,
|
||||||
// NOTE: The newFocus isn't editable that also means it's not in
|
// NOTE: The newFocus isn't editable that also means it's not in
|
||||||
// designMode. In designMode, all contents are not focusable.
|
// designMode. In designMode, all contents are not focusable.
|
||||||
if (newFocus && !newFocus->IsEditable()) {
|
if (newFocus && !newFocus->IsEditable()) {
|
||||||
nsIDocument *doc = newFocus->GetCurrentDoc();
|
nsIDocument *doc = newFocus->GetCrossShadowCurrentDoc();
|
||||||
if (doc && newFocus == doc->GetRootElement()) {
|
if (doc && newFocus == doc->GetRootElement()) {
|
||||||
nsIContent *bodyContent =
|
nsIContent *bodyContent =
|
||||||
nsLayoutUtils::GetEditableRootContentByContentEditable(doc);
|
nsLayoutUtils::GetEditableRootContentByContentEditable(doc);
|
||||||
|
@ -4633,7 +4633,8 @@ EventStateManager::SetContentState(nsIContent* aContent, EventStates aState)
|
||||||
newHover = aContent;
|
newHover = aContent;
|
||||||
} else {
|
} else {
|
||||||
NS_ASSERTION(!aContent ||
|
NS_ASSERTION(!aContent ||
|
||||||
aContent->GetCurrentDoc() == mPresContext->PresShell()->GetDocument(),
|
aContent->GetCrossShadowCurrentDoc() ==
|
||||||
|
mPresContext->PresShell()->GetDocument(),
|
||||||
"Unexpected document");
|
"Unexpected document");
|
||||||
nsIFrame *frame = aContent ? aContent->GetPrimaryFrame() : nullptr;
|
nsIFrame *frame = aContent ? aContent->GetPrimaryFrame() : nullptr;
|
||||||
if (frame && nsLayoutUtils::IsViewportScrollbarFrame(frame)) {
|
if (frame && nsLayoutUtils::IsViewportScrollbarFrame(frame)) {
|
||||||
|
|
|
@ -38,17 +38,6 @@ public:
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
MOZ_CONSTEXPR EventStates(const EventStates& aEventStates)
|
|
||||||
: mStates(aEventStates.mStates)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
EventStates& operator=(const EventStates& aEventStates)
|
|
||||||
{
|
|
||||||
mStates = aEventStates.mStates;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
EventStates MOZ_CONSTEXPR operator|(const EventStates& aEventStates) const
|
EventStates MOZ_CONSTEXPR operator|(const EventStates& aEventStates) const
|
||||||
{
|
{
|
||||||
return EventStates(mStates | aEventStates.mStates);
|
return EventStates(mStates | aEventStates.mStates);
|
||||||
|
|
|
@ -10,68 +10,66 @@ support-files =
|
||||||
turnConfig.js
|
turnConfig.js
|
||||||
|
|
||||||
[test_dataChannel_basicAudio.html]
|
[test_dataChannel_basicAudio.html]
|
||||||
skip-if = toolkit == 'gonk' #Bug 962984 for debug, bug 963244 for opt
|
skip-if = toolkit == 'gonk' # Bug 962984 for debug, bug 963244 for opt
|
||||||
[test_dataChannel_basicAudioVideo.html]
|
[test_dataChannel_basicAudioVideo.html]
|
||||||
# Disabled on OS X for bug 930481 timeouts
|
skip-if = toolkit == 'gonk' # b2g(Bug 960442, video support for WebRTC is disabled on b2g)
|
||||||
skip-if = os == 'mac' || toolkit=='gonk' # b2g(Bug 960442, video support for WebRTC is disabled on b2g)
|
|
||||||
[test_dataChannel_basicAudioVideoCombined.html]
|
[test_dataChannel_basicAudioVideoCombined.html]
|
||||||
# Disabled on OS X for bug 930481 timeouts
|
skip-if = toolkit == 'gonk' # b2g(Bug 960442, video support for WebRTC is disabled on b2g)
|
||||||
skip-if = os == 'mac' || toolkit=='gonk' # b2g(Bug 960442, video support for WebRTC is disabled on b2g)
|
|
||||||
[test_dataChannel_basicDataOnly.html]
|
[test_dataChannel_basicDataOnly.html]
|
||||||
[test_dataChannel_basicVideo.html]
|
[test_dataChannel_basicVideo.html]
|
||||||
skip-if = toolkit=='gonk' # b2g emulator seems to bee too slow (Bug 1016498 and 1008080)
|
skip-if = toolkit == 'gonk' # b2g(Bug 960442, video support for WebRTC is disabled on b2g)
|
||||||
[test_dataChannel_bug1013809.html]
|
[test_dataChannel_bug1013809.html]
|
||||||
skip-if = toolkit=='gonk' # b2g(Bug 960442, video support for WebRTC is disabled on b2g)
|
skip-if = (toolkit == 'gonk' && debug) # b2g emulator seems to be too slow (Bug 1016498 and 1008080)
|
||||||
[test_dataChannel_noOffer.html]
|
[test_dataChannel_noOffer.html]
|
||||||
[test_getUserMedia_basicAudio.html]
|
[test_getUserMedia_basicAudio.html]
|
||||||
skip-if = (toolkit == 'gonk' && debug) #debug-only failure
|
skip-if = (toolkit == 'gonk' && debug) # debug-only failure
|
||||||
[test_getUserMedia_basicVideo.html]
|
[test_getUserMedia_basicVideo.html]
|
||||||
skip-if = (toolkit == 'gonk' && debug) #debug-only failure
|
skip-if = (toolkit == 'gonk' && debug) # debug-only failure
|
||||||
[test_getUserMedia_basicVideoAudio.html]
|
[test_getUserMedia_basicVideoAudio.html]
|
||||||
skip-if = (toolkit == 'gonk' && debug) #debug-only failure, turned an intermittent (bug 962579) into a permanant orange
|
skip-if = (toolkit == 'gonk' && debug) # debug-only failure, turned an intermittent (bug 962579) into a permanant orange
|
||||||
[test_getUserMedia_constraints.html]
|
[test_getUserMedia_constraints.html]
|
||||||
skip-if = (toolkit=='gonk' || toolkit=='android') # Bug 907352, backwards-compatible behavior on mobile only
|
skip-if = toolkit == 'gonk' || toolkit == 'android' # Bug 907352, backwards-compatible behavior on mobile only
|
||||||
[test_getUserMedia_constraints_mobile.html]
|
[test_getUserMedia_constraints_mobile.html]
|
||||||
skip-if = (toolkit!='gonk' && toolkit!='android') # Bug 907352, backwards-compatible behavior on mobile only
|
skip-if = toolkit != 'gonk' && toolkit != 'android' # Bug 907352, backwards-compatible behavior on mobile only
|
||||||
[test_getUserMedia_exceptions.html]
|
[test_getUserMedia_exceptions.html]
|
||||||
[test_getUserMedia_gumWithinGum.html]
|
[test_getUserMedia_gumWithinGum.html]
|
||||||
[test_getUserMedia_playAudioTwice.html]
|
[test_getUserMedia_playAudioTwice.html]
|
||||||
[test_getUserMedia_playVideoAudioTwice.html]
|
[test_getUserMedia_playVideoAudioTwice.html]
|
||||||
skip-if = (toolkit == 'gonk' && debug) #debug-only failure; bug 926558
|
skip-if = (toolkit == 'gonk' && debug) # debug-only failure; bug 926558
|
||||||
[test_getUserMedia_playVideoTwice.html]
|
[test_getUserMedia_playVideoTwice.html]
|
||||||
[test_getUserMedia_stopAudioStream.html]
|
[test_getUserMedia_stopAudioStream.html]
|
||||||
[test_getUserMedia_stopAudioStreamWithFollowupAudio.html]
|
[test_getUserMedia_stopAudioStreamWithFollowupAudio.html]
|
||||||
[test_getUserMedia_stopVideoAudioStream.html]
|
[test_getUserMedia_stopVideoAudioStream.html]
|
||||||
skip-if = (toolkit == 'gonk' && debug) #debug-only failure
|
skip-if = (toolkit == 'gonk' && debug) # debug-only failure
|
||||||
[test_getUserMedia_stopVideoAudioStreamWithFollowupVideoAudio.html]
|
[test_getUserMedia_stopVideoAudioStreamWithFollowupVideoAudio.html]
|
||||||
[test_getUserMedia_stopVideoStream.html]
|
[test_getUserMedia_stopVideoStream.html]
|
||||||
[test_getUserMedia_stopVideoStreamWithFollowupVideo.html]
|
[test_getUserMedia_stopVideoStreamWithFollowupVideo.html]
|
||||||
[test_getUserMedia_peerIdentity.html]
|
[test_getUserMedia_peerIdentity.html]
|
||||||
[test_peerConnection_addCandidateInHaveLocalOffer.html]
|
[test_peerConnection_addCandidateInHaveLocalOffer.html]
|
||||||
[test_peerConnection_basicAudio.html]
|
[test_peerConnection_basicAudio.html]
|
||||||
skip-if = (toolkit == 'gonk' && debug) #Bug 962984, test fail on b2g debug build
|
skip-if = (toolkit == 'gonk' && debug) # Bug 962984, test fail on b2g debug build
|
||||||
[test_peerConnection_basicAudioVideo.html]
|
[test_peerConnection_basicAudioVideo.html]
|
||||||
skip-if = toolkit=='gonk' # b2g(Bug 960442, video support for WebRTC is disabled on b2g)
|
skip-if = toolkit == 'gonk' # b2g(Bug 960442, video support for WebRTC is disabled on b2g)
|
||||||
[test_peerConnection_basicAudioVideoCombined.html]
|
[test_peerConnection_basicAudioVideoCombined.html]
|
||||||
skip-if = toolkit=='gonk' # b2g(Bug 960442, video support for WebRTC is disabled on b2g)
|
skip-if = toolkit == 'gonk' # b2g(Bug 960442, video support for WebRTC is disabled on b2g)
|
||||||
[test_peerConnection_basicVideo.html]
|
[test_peerConnection_basicVideo.html]
|
||||||
skip-if = toolkit=='gonk' # b2g(Bug 960442, video support for WebRTC is disabled on b2g)
|
skip-if = toolkit == 'gonk' # b2g(Bug 960442, video support for WebRTC is disabled on b2g)
|
||||||
[test_peerConnection_bug822674.html]
|
[test_peerConnection_bug822674.html]
|
||||||
[test_peerConnection_bug825703.html]
|
[test_peerConnection_bug825703.html]
|
||||||
[test_peerConnection_bug827843.html]
|
[test_peerConnection_bug827843.html]
|
||||||
skip-if = toolkit=='gonk' # b2g(Bug 960442, video support for WebRTC is disabled on b2g)
|
skip-if = toolkit == 'gonk' # b2g(Bug 960442, video support for WebRTC is disabled on b2g)
|
||||||
[test_peerConnection_bug834153.html]
|
[test_peerConnection_bug834153.html]
|
||||||
[test_peerConnection_bug835370.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_bug1013809.html]
|
||||||
|
skip-if = (toolkit == 'gonk' && debug) # b2g emulator seems to be too slow (Bug 1016498 and 1008080)
|
||||||
[test_peerConnection_close.html]
|
[test_peerConnection_close.html]
|
||||||
[test_peerConnection_errorCallbacks.html]
|
[test_peerConnection_errorCallbacks.html]
|
||||||
[test_peerConnection_offerRequiresReceiveAudio.html]
|
[test_peerConnection_offerRequiresReceiveAudio.html]
|
||||||
skip-if = toolkit=='gonk' # b2g(Bug 960442, video support for WebRTC is disabled on b2g)
|
skip-if = toolkit == 'gonk' # b2g(Bug 960442, video support for WebRTC is disabled on b2g)
|
||||||
[test_peerConnection_offerRequiresReceiveVideo.html]
|
[test_peerConnection_offerRequiresReceiveVideo.html]
|
||||||
skip-if = toolkit=='gonk' # b2g(Bug 960442, video support for WebRTC is disabled on b2g)
|
skip-if = toolkit == 'gonk' # b2g(Bug 960442, video support for WebRTC is disabled on b2g)
|
||||||
[test_peerConnection_offerRequiresReceiveVideoAudio.html]
|
[test_peerConnection_offerRequiresReceiveVideoAudio.html]
|
||||||
skip-if = toolkit=='gonk' # b2g(Bug 960442, video support for WebRTC is disabled on b2g)
|
skip-if = toolkit == 'gonk' # b2g(Bug 960442, video support for WebRTC is disabled on b2g)
|
||||||
[test_peerConnection_setLocalAnswerInHaveLocalOffer.html]
|
[test_peerConnection_setLocalAnswerInHaveLocalOffer.html]
|
||||||
[test_peerConnection_setLocalAnswerInStable.html]
|
[test_peerConnection_setLocalAnswerInStable.html]
|
||||||
[test_peerConnection_setLocalOfferInHaveRemoteOffer.html]
|
[test_peerConnection_setLocalOfferInHaveRemoteOffer.html]
|
||||||
|
@ -79,7 +77,7 @@ skip-if = toolkit=='gonk' # b2g(Bug 960442, video support for WebRTC is disabled
|
||||||
[test_peerConnection_setRemoteAnswerInStable.html]
|
[test_peerConnection_setRemoteAnswerInStable.html]
|
||||||
[test_peerConnection_setRemoteOfferInHaveLocalOffer.html]
|
[test_peerConnection_setRemoteOfferInHaveLocalOffer.html]
|
||||||
[test_peerConnection_throwInCallbacks.html]
|
[test_peerConnection_throwInCallbacks.html]
|
||||||
skip-if = toolkit=='gonk' # b2g(Bug 960442, video support for WebRTC is disabled on b2g)
|
skip-if = toolkit == 'gonk' # b2g(Bug 960442, video support for WebRTC is disabled on b2g)
|
||||||
[test_peerConnection_toJSON.html]
|
[test_peerConnection_toJSON.html]
|
||||||
|
|
||||||
# Bug 950317: Hack for making a cleanup hook after finishing all WebRTC cases
|
# Bug 950317: Hack for making a cleanup hook after finishing all WebRTC cases
|
||||||
|
|
|
@ -6,3 +6,4 @@ tail =
|
||||||
[test_multisend.js]
|
[test_multisend.js]
|
||||||
[test_tcpserversocket.js]
|
[test_tcpserversocket.js]
|
||||||
run-sequentially = Uses hardcoded port, bug 903830.
|
run-sequentially = Uses hardcoded port, bug 903830.
|
||||||
|
skip-if = os == 'mac' # bug 953208 - frequent timeouts on OSX
|
||||||
|
|
|
@ -396,8 +396,13 @@ NS_IMETHODIMP
|
||||||
NotificationObserver::Observe(nsISupports* aSubject, const char* aTopic,
|
NotificationObserver::Observe(nsISupports* aSubject, const char* aTopic,
|
||||||
const char16_t* aData)
|
const char16_t* aData)
|
||||||
{
|
{
|
||||||
|
nsCOMPtr<nsPIDOMWindow> window = mNotification->GetOwner();
|
||||||
|
if (!window) {
|
||||||
|
// Window has been closed, this observer is not valid anymore
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
if (!strcmp("alertclickcallback", aTopic)) {
|
if (!strcmp("alertclickcallback", aTopic)) {
|
||||||
nsCOMPtr<nsPIDOMWindow> window = mNotification->GetOwner();
|
|
||||||
nsIDocument* doc = window ? window->GetExtantDoc() : nullptr;
|
nsIDocument* doc = window ? window->GetExtantDoc() : nullptr;
|
||||||
if (doc) {
|
if (doc) {
|
||||||
nsContentUtils::DispatchChromeEvent(doc, window,
|
nsContentUtils::DispatchChromeEvent(doc, window,
|
||||||
|
|
|
@ -122,7 +122,7 @@ WifiGeoPositionProvider.prototype = {
|
||||||
// This platform doesn't have the settings interface, and that is just peachy
|
// This platform doesn't have the settings interface, and that is just peachy
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gWifiScanningEnabled) {
|
if (gWifiScanningEnabled && Cc["@mozilla.org/wifi/monitor;1"]) {
|
||||||
this.wifiService = Cc["@mozilla.org/wifi/monitor;1"].getService(Components.interfaces.nsIWifiMonitor);
|
this.wifiService = Cc["@mozilla.org/wifi/monitor;1"].getService(Components.interfaces.nsIWifiMonitor);
|
||||||
this.wifiService.startWatching(this);
|
this.wifiService.startWatching(this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,10 +10,13 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=806506
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="tall" id="bodydiv"></div>
|
<div class="tall" id="bodydiv"></div>
|
||||||
|
<div id="container"></div>
|
||||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=806506">Bug 806506</a>
|
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=806506">Bug 806506</a>
|
||||||
<script>
|
<script>
|
||||||
// Create ShadowRoot.
|
// Create ShadowRoot.
|
||||||
|
var container = document.getElementById("container");
|
||||||
var elem = document.createElement("div");
|
var elem = document.createElement("div");
|
||||||
|
container.appendChild(elem); // Put ShadowRoot host in document.
|
||||||
var root = elem.createShadowRoot();
|
var root = elem.createShadowRoot();
|
||||||
|
|
||||||
// A style element that will be appended into the ShadowRoot.
|
// A style element that will be appended into the ShadowRoot.
|
||||||
|
|
|
@ -10,10 +10,13 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=806506
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="tall" id="bodydiv"></div>
|
<div class="tall" id="bodydiv"></div>
|
||||||
|
<div id="container"></div>
|
||||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=806506">Bug 806506</a>
|
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=806506">Bug 806506</a>
|
||||||
<script>
|
<script>
|
||||||
// Create ShadowRoot.
|
// Create ShadowRoot.
|
||||||
|
var container = document.getElementById("container");
|
||||||
var elem = document.createElement("div");
|
var elem = document.createElement("div");
|
||||||
|
container.appendChild(elem); // Put ShadowRoot host in document.
|
||||||
var firstRoot = elem.createShadowRoot();
|
var firstRoot = elem.createShadowRoot();
|
||||||
var secondRoot = elem.createShadowRoot();
|
var secondRoot = elem.createShadowRoot();
|
||||||
var thirdRoot = elem.createShadowRoot();
|
var thirdRoot = elem.createShadowRoot();
|
||||||
|
|
|
@ -9,10 +9,13 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=806506
|
||||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<div id="container"></div>
|
||||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=806506">Bug 806506</a>
|
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=806506">Bug 806506</a>
|
||||||
<script>
|
<script>
|
||||||
// Create ShadowRoot.
|
// Create ShadowRoot.
|
||||||
|
var container = document.getElementById("container");
|
||||||
var elem = document.createElement("div");
|
var elem = document.createElement("div");
|
||||||
|
container.appendChild(elem); // Put ShadowRoot host in document.
|
||||||
var root = elem.createShadowRoot();
|
var root = elem.createShadowRoot();
|
||||||
|
|
||||||
// Style elements that will be appended into the ShadowRoot.
|
// Style elements that will be appended into the ShadowRoot.
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
/* -*- 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/. */
|
||||||
|
|
||||||
|
enum AutoCompleteErrorReason {
|
||||||
|
"",
|
||||||
|
"cancel",
|
||||||
|
"disabled",
|
||||||
|
"invalid"
|
||||||
|
};
|
||||||
|
|
||||||
|
[Pref="dom.forms.requestAutocomplete",
|
||||||
|
Constructor(DOMString type, optional AutocompleteErrorEventInit eventInitDict)]
|
||||||
|
interface AutocompleteErrorEvent : Event
|
||||||
|
{
|
||||||
|
readonly attribute AutoCompleteErrorReason reason;
|
||||||
|
};
|
||||||
|
|
||||||
|
dictionary AutocompleteErrorEventInit : EventInit
|
||||||
|
{
|
||||||
|
AutoCompleteErrorReason reason = "";
|
||||||
|
};
|
|
@ -45,4 +45,7 @@ interface HTMLFormElement : HTMLElement {
|
||||||
void submit();
|
void submit();
|
||||||
void reset();
|
void reset();
|
||||||
boolean checkValidity();
|
boolean checkValidity();
|
||||||
|
|
||||||
|
[Pref="dom.forms.requestAutocomplete"]
|
||||||
|
void requestAutocomplete();
|
||||||
};
|
};
|
||||||
|
|
|
@ -102,6 +102,9 @@ partial interface HTMLMediaElement {
|
||||||
attribute boolean mozPreservesPitch;
|
attribute boolean mozPreservesPitch;
|
||||||
readonly attribute boolean mozAutoplayEnabled;
|
readonly attribute boolean mozAutoplayEnabled;
|
||||||
|
|
||||||
|
// NB: for internal use with the video controls:
|
||||||
|
[Func="IsChromeOrXBL"] attribute boolean mozMediaStatisticsShowing;
|
||||||
|
|
||||||
// Mozilla extension: stream capture
|
// Mozilla extension: stream capture
|
||||||
[Throws]
|
[Throws]
|
||||||
MediaStream mozCaptureStream();
|
MediaStream mozCaptureStream();
|
||||||
|
@ -130,3 +133,25 @@ partial interface HTMLMediaElement {
|
||||||
// because of the audiochannel manager.
|
// because of the audiochannel manager.
|
||||||
// * onmozinterruptend - called when the interruption is concluded
|
// * onmozinterruptend - called when the interruption is concluded
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum MediaWaitingFor {
|
||||||
|
"none",
|
||||||
|
"data",
|
||||||
|
"key"
|
||||||
|
};
|
||||||
|
|
||||||
|
// Encrypted Media Extensions
|
||||||
|
partial interface HTMLMediaElement {
|
||||||
|
[Pref="media.eme.enabled"]
|
||||||
|
readonly attribute MediaKeys? mediaKeys;
|
||||||
|
|
||||||
|
// Promise<any>
|
||||||
|
[Pref="media.eme.enabled", Throws, NewObject]
|
||||||
|
Promise setMediaKeys(MediaKeys? mediaKeys);
|
||||||
|
|
||||||
|
[Pref="media.eme.enabled"]
|
||||||
|
attribute EventHandler onneedkey;
|
||||||
|
|
||||||
|
[Pref="media.eme.enabled"]
|
||||||
|
readonly attribute MediaWaitingFor waitingFor;
|
||||||
|
};
|
||||||
|
|
|
@ -19,3 +19,9 @@ interface HTMLSourceElement : HTMLElement {
|
||||||
[SetterThrows]
|
[SetterThrows]
|
||||||
attribute DOMString media;
|
attribute DOMString media;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Encrypted Media Extensions
|
||||||
|
partial interface HTMLSourceElement {
|
||||||
|
[Pref="media.eme.enabled"]
|
||||||
|
attribute DOMString keySystem;
|
||||||
|
};
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
/* -*- 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/.
|
||||||
|
*
|
||||||
|
* The origin of this IDL file is
|
||||||
|
* https://dvcs.w3.org/hg/html-media/raw-file/default/encrypted-media/encrypted-media.html
|
||||||
|
*
|
||||||
|
* Copyright © 2014 W3C® (MIT, ERCIM, Keio, Beihang), All Rights Reserved.
|
||||||
|
* W3C liability, trademark and document use rules apply.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// According to the spec, "The future of error events and MediaKeyError
|
||||||
|
// is uncertain."
|
||||||
|
// https://www.w3.org/Bugs/Public/show_bug.cgi?id=21798
|
||||||
|
[Pref="media.eme.enabled"]
|
||||||
|
interface MediaKeyError : Event {
|
||||||
|
readonly attribute unsigned long systemCode;
|
||||||
|
};
|
|
@ -0,0 +1,23 @@
|
||||||
|
/* -*- 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/.
|
||||||
|
*
|
||||||
|
* The origin of this IDL file is
|
||||||
|
* https://dvcs.w3.org/hg/html-media/raw-file/default/encrypted-media/encrypted-media.html
|
||||||
|
*
|
||||||
|
* Copyright © 2014 W3C® (MIT, ERCIM, Keio, Beihang), All Rights Reserved.
|
||||||
|
* W3C liability, trademark and document use rules apply.
|
||||||
|
*/
|
||||||
|
|
||||||
|
[Pref="media.eme.enabled", Constructor(DOMString type, optional MediaKeyMessageEventInit eventInitDict)]
|
||||||
|
interface MediaKeyMessageEvent : Event {
|
||||||
|
[Throws]
|
||||||
|
readonly attribute Uint8Array message;
|
||||||
|
readonly attribute DOMString? destinationURL;
|
||||||
|
};
|
||||||
|
|
||||||
|
dictionary MediaKeyMessageEventInit : EventInit {
|
||||||
|
Uint8Array message;
|
||||||
|
DOMString? destinationURL = "";
|
||||||
|
};
|
|
@ -0,0 +1,23 @@
|
||||||
|
/* -*- 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/.
|
||||||
|
*
|
||||||
|
* The origin of this IDL file is
|
||||||
|
* https://dvcs.w3.org/hg/html-media/raw-file/default/encrypted-media/encrypted-media.html
|
||||||
|
*
|
||||||
|
* Copyright © 2014 W3C® (MIT, ERCIM, Keio, Beihang), All Rights Reserved.
|
||||||
|
* W3C liability, trademark and document use rules apply.
|
||||||
|
*/
|
||||||
|
|
||||||
|
[Pref="media.eme.enabled", Constructor(DOMString type, optional MediaKeyNeededEventInit eventInitDict)]
|
||||||
|
interface MediaKeyNeededEvent : Event {
|
||||||
|
readonly attribute DOMString initDataType;
|
||||||
|
[Throws]
|
||||||
|
readonly attribute Uint8Array? initData;
|
||||||
|
};
|
||||||
|
|
||||||
|
dictionary MediaKeyNeededEventInit : EventInit {
|
||||||
|
DOMString initDataType = "";
|
||||||
|
Uint8Array? initData;
|
||||||
|
};
|
|
@ -0,0 +1,43 @@
|
||||||
|
/* -*- 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/.
|
||||||
|
*
|
||||||
|
* The origin of this IDL file is
|
||||||
|
* https://dvcs.w3.org/hg/html-media/raw-file/default/encrypted-media/encrypted-media.html
|
||||||
|
*
|
||||||
|
* Copyright © 2014 W3C® (MIT, ERCIM, Keio, Beihang), All Rights Reserved.
|
||||||
|
* W3C liability, trademark and document use rules apply.
|
||||||
|
*/
|
||||||
|
|
||||||
|
[Pref="media.eme.enabled"]
|
||||||
|
interface MediaKeySession : EventTarget {
|
||||||
|
// error state
|
||||||
|
readonly attribute MediaKeyError? error;
|
||||||
|
|
||||||
|
// session properties
|
||||||
|
readonly attribute DOMString keySystem;
|
||||||
|
readonly attribute DOMString sessionId;
|
||||||
|
|
||||||
|
// Invalid WebIDL, doesn't work.
|
||||||
|
// https://www.w3.org/Bugs/Public/show_bug.cgi?id=25594
|
||||||
|
// readonly attribute Array<Uint8Array> usableKeyIds;
|
||||||
|
|
||||||
|
readonly attribute unrestricted double expiration;
|
||||||
|
|
||||||
|
// Promise<any>
|
||||||
|
readonly attribute Promise closed;
|
||||||
|
|
||||||
|
// session operations
|
||||||
|
//Promise<any>
|
||||||
|
[NewObject]
|
||||||
|
Promise update(Uint8Array response);
|
||||||
|
|
||||||
|
// Promise<any>
|
||||||
|
[NewObject]
|
||||||
|
Promise close();
|
||||||
|
|
||||||
|
// Promise<any>
|
||||||
|
[NewObject]
|
||||||
|
Promise remove();
|
||||||
|
};
|
|
@ -0,0 +1,37 @@
|
||||||
|
/* -*- 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/.
|
||||||
|
*
|
||||||
|
* The origin of this IDL file is
|
||||||
|
* https://dvcs.w3.org/hg/html-media/raw-file/default/encrypted-media/encrypted-media.html
|
||||||
|
*
|
||||||
|
* Copyright © 2014 W3C® (MIT, ERCIM, Keio, Beihang), All Rights Reserved.
|
||||||
|
* W3C liability, trademark and document use rules apply.
|
||||||
|
*/
|
||||||
|
|
||||||
|
enum IsTypeSupportedResult { "" /* empty string */, "maybe", "probably" };
|
||||||
|
enum SessionType { "temporary", "persistent" };
|
||||||
|
|
||||||
|
[Pref="media.eme.enabled"]
|
||||||
|
interface MediaKeys {
|
||||||
|
readonly attribute DOMString keySystem;
|
||||||
|
|
||||||
|
// Promise<MediaKeySession>
|
||||||
|
[NewObject]
|
||||||
|
Promise createSession(DOMString initDataType, Uint8Array initData, optional SessionType sessionType = "temporary");
|
||||||
|
|
||||||
|
// Promise<MediaKeySession>
|
||||||
|
[NewObject]
|
||||||
|
Promise loadSession(DOMString sessionId);
|
||||||
|
|
||||||
|
// Promise<any>
|
||||||
|
[NewObject]
|
||||||
|
Promise setServerCertificate(Uint8Array serverCertificate);
|
||||||
|
|
||||||
|
// Promise<MediaKeys>
|
||||||
|
[Throws,NewObject]
|
||||||
|
static Promise create(DOMString keySystem);
|
||||||
|
static IsTypeSupportedResult isTypeSupported(DOMString keySystem, optional DOMString initDataType, optional DOMString contentType, optional DOMString capability);
|
||||||
|
|
||||||
|
};
|
|
@ -231,6 +231,11 @@ WEBIDL_FILES = [
|
||||||
'LockedFile.webidl',
|
'LockedFile.webidl',
|
||||||
'MediaElementAudioSourceNode.webidl',
|
'MediaElementAudioSourceNode.webidl',
|
||||||
'MediaError.webidl',
|
'MediaError.webidl',
|
||||||
|
'MediaKeyError.webidl',
|
||||||
|
'MediaKeyMessageEvent.webidl',
|
||||||
|
'MediaKeyNeededEvent.webidl',
|
||||||
|
'MediaKeys.webidl',
|
||||||
|
'MediaKeySession.webidl',
|
||||||
'MediaList.webidl',
|
'MediaList.webidl',
|
||||||
'MediaQueryList.webidl',
|
'MediaQueryList.webidl',
|
||||||
'MediaRecorder.webidl',
|
'MediaRecorder.webidl',
|
||||||
|
@ -623,6 +628,7 @@ if not CONFIG['MOZ_DISABLE_CRYPTOLEGACY']:
|
||||||
]
|
]
|
||||||
|
|
||||||
GENERATED_EVENTS_WEBIDL_FILES = [
|
GENERATED_EVENTS_WEBIDL_FILES = [
|
||||||
|
'AutocompleteErrorEvent.webidl',
|
||||||
'BlobEvent.webidl',
|
'BlobEvent.webidl',
|
||||||
'CallGroupErrorEvent.webidl',
|
'CallGroupErrorEvent.webidl',
|
||||||
'CFStateChangeEvent.webidl',
|
'CFStateChangeEvent.webidl',
|
||||||
|
|
|
@ -28,6 +28,12 @@ BEGIN_WORKERS_NAMESPACE
|
||||||
* | Killing | yes | yes | doesn't run |
|
* | Killing | yes | yes | doesn't run |
|
||||||
* +-------------+-------------+-----------------+----------------+
|
* +-------------+-------------+-----------------+----------------+
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef Status
|
||||||
|
/* Xlib headers insist on this for some reason... Nuke it because
|
||||||
|
it'll override our member name */
|
||||||
|
#undef Status
|
||||||
|
#endif
|
||||||
enum Status
|
enum Status
|
||||||
{
|
{
|
||||||
// Not yet scheduled.
|
// Not yet scheduled.
|
||||||
|
|
|
@ -445,6 +445,27 @@ APZCTreeManager::ReceiveInputEvent(const InputData& aEvent,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
} case PANGESTURE_INPUT: {
|
||||||
|
const PanGestureInput& panInput = aEvent.AsPanGestureInput();
|
||||||
|
bool inOverscrolledApzc = false;
|
||||||
|
nsRefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(panInput.mPanStartPoint,
|
||||||
|
&inOverscrolledApzc);
|
||||||
|
if (apzc) {
|
||||||
|
if (panInput.mType == PanGestureInput::PANGESTURE_START ||
|
||||||
|
panInput.mType == PanGestureInput::PANGESTURE_MOMENTUMSTART) {
|
||||||
|
BuildOverscrollHandoffChain(apzc);
|
||||||
|
}
|
||||||
|
apzc->GetGuid(aOutTargetGuid);
|
||||||
|
GetInputTransforms(apzc, transformToApzc, transformToGecko);
|
||||||
|
PanGestureInput inputForApzc(panInput);
|
||||||
|
ApplyTransform(&(inputForApzc.mPanStartPoint), transformToApzc);
|
||||||
|
result = apzc->ReceiveInputEvent(inputForApzc);
|
||||||
|
if (panInput.mType == PanGestureInput::PANGESTURE_END ||
|
||||||
|
panInput.mType == PanGestureInput::PANGESTURE_MOMENTUMEND) {
|
||||||
|
ClearOverscrollHandoffChain();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
} case PINCHGESTURE_INPUT: {
|
} case PINCHGESTURE_INPUT: {
|
||||||
const PinchGestureInput& pinchInput = aEvent.AsPinchGestureInput();
|
const PinchGestureInput& pinchInput = aEvent.AsPinchGestureInput();
|
||||||
bool inOverscrolledApzc = false;
|
bool inOverscrolledApzc = false;
|
||||||
|
|
|
@ -216,13 +216,36 @@ typedef GeckoContentController::APZStateChange APZStateChange;
|
||||||
* Pref that enables overscrolling. If this is disabled, excess scroll that
|
* Pref that enables overscrolling. If this is disabled, excess scroll that
|
||||||
* cannot be handed off is discarded.
|
* cannot be handed off is discarded.
|
||||||
*
|
*
|
||||||
* "apz.overscroll.snap_back_accel"
|
* "apz.overscroll.fling_friction"
|
||||||
* Amount of acceleration applied during the snap-back animation.
|
* Amount of friction applied during flings when in overscroll.
|
||||||
*
|
*
|
||||||
* "apz.overscroll.snap_back_init_vel"
|
* "apz.overscroll.fling_stopped_threshold"
|
||||||
* Initial velocity of a snap-back animation along one axis.
|
* When flinging in an overscrolled state, if the velocity goes below this
|
||||||
|
* number, we stop the fling.
|
||||||
* Units: screen pixels per millisecond
|
* Units: screen pixels per millisecond
|
||||||
* requests.
|
*
|
||||||
|
* "apz.overscroll.clamping"
|
||||||
|
* The maximum proportion of the composition bounds which can become blank
|
||||||
|
* as a result of overscroll, along the axis of overscroll.
|
||||||
|
*
|
||||||
|
* "apz.overscroll.z_effect"
|
||||||
|
* The fraction of "apz.overscroll.clamping" which can become blank as a result
|
||||||
|
* of overscroll, along the axis opposite to the axis of overscroll. Called
|
||||||
|
* "z_effect" because the shrinking that brings about the blank space on the
|
||||||
|
* opposite axis creates the effect of the page moving away from you along a
|
||||||
|
* "z" axis.
|
||||||
|
*
|
||||||
|
* "apz.overscroll.snap_back.spring_stiffness"
|
||||||
|
* The stiffness of the spring used in the physics model for the overscroll
|
||||||
|
* snap-back animation.
|
||||||
|
*
|
||||||
|
* "apz.overscroll.snap_back.spring_damping"
|
||||||
|
* The friction of the spring used in the physics model for the overscroll
|
||||||
|
* snap-back animation.
|
||||||
|
*
|
||||||
|
* "apz.overscroll.snap_back.mass"
|
||||||
|
* The mass of the page in the physics model for the overscroll snap-back
|
||||||
|
* animation.
|
||||||
*
|
*
|
||||||
* "apz.pan_repaint_interval"
|
* "apz.pan_repaint_interval"
|
||||||
* Maximum amount of time while panning before sending a viewport change. This
|
* Maximum amount of time while panning before sending a viewport change. This
|
||||||
|
@ -471,17 +494,15 @@ private:
|
||||||
class OverscrollSnapBackAnimation: public AsyncPanZoomAnimation {
|
class OverscrollSnapBackAnimation: public AsyncPanZoomAnimation {
|
||||||
public:
|
public:
|
||||||
OverscrollSnapBackAnimation(AsyncPanZoomController& aApzc)
|
OverscrollSnapBackAnimation(AsyncPanZoomController& aApzc)
|
||||||
: mApzc(aApzc)
|
: mApzc(aApzc) {}
|
||||||
{
|
|
||||||
mApzc.mX.StartSnapBack();
|
|
||||||
mApzc.mY.StartSnapBack();
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool Sample(FrameMetrics& aFrameMetrics,
|
virtual bool Sample(FrameMetrics& aFrameMetrics,
|
||||||
const TimeDuration& aDelta) MOZ_OVERRIDE
|
const TimeDuration& aDelta) MOZ_OVERRIDE
|
||||||
{
|
{
|
||||||
return mApzc.mX.SampleSnapBack(aDelta)
|
// Can't inline these variables due to short-circuit evaluation.
|
||||||
|| mApzc.mY.SampleSnapBack(aDelta);
|
bool continueX = mApzc.mX.SampleSnapBack(aDelta);
|
||||||
|
bool continueY = mApzc.mY.SampleSnapBack(aDelta);
|
||||||
|
return continueX || continueY;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -693,6 +714,21 @@ nsEventStatus AsyncPanZoomController::HandleInputEvent(const InputData& aEvent)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case PANGESTURE_INPUT: {
|
||||||
|
const PanGestureInput& panGestureInput = aEvent.AsPanGestureInput();
|
||||||
|
switch (panGestureInput.mType) {
|
||||||
|
case PanGestureInput::PANGESTURE_MAYSTART: rv = OnPanMayBegin(panGestureInput); break;
|
||||||
|
case PanGestureInput::PANGESTURE_CANCELLED: rv = OnPanCancelled(panGestureInput); break;
|
||||||
|
case PanGestureInput::PANGESTURE_START: rv = OnPanBegin(panGestureInput); break;
|
||||||
|
case PanGestureInput::PANGESTURE_PAN: rv = OnPan(panGestureInput, true); break;
|
||||||
|
case PanGestureInput::PANGESTURE_END: rv = OnPanEnd(panGestureInput); break;
|
||||||
|
case PanGestureInput::PANGESTURE_MOMENTUMSTART: rv = OnPanMomentumStart(panGestureInput); break;
|
||||||
|
case PanGestureInput::PANGESTURE_MOMENTUMPAN: rv = OnPan(panGestureInput, false); break;
|
||||||
|
case PanGestureInput::PANGESTURE_MOMENTUMEND: rv = OnPanMomentumEnd(panGestureInput); break;
|
||||||
|
default: NS_WARNING("Unhandled pan gesture"); break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
default: NS_WARNING("Unhandled input event"); break;
|
default: NS_WARNING("Unhandled input event"); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1064,6 +1100,93 @@ AsyncPanZoomController::ConvertToGecko(const ScreenPoint& aPoint, CSSPoint* aOut
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsEventStatus AsyncPanZoomController::OnPanMayBegin(const PanGestureInput& aEvent) {
|
||||||
|
APZC_LOG("%p got a pan-maybegin in state %d\n", this, mState);
|
||||||
|
|
||||||
|
mX.StartTouch(aEvent.mPanStartPoint.x, aEvent.mTime);
|
||||||
|
mY.StartTouch(aEvent.mPanStartPoint.y, aEvent.mTime);
|
||||||
|
CancelAnimation();
|
||||||
|
|
||||||
|
return nsEventStatus_eConsumeNoDefault;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsEventStatus AsyncPanZoomController::OnPanCancelled(const PanGestureInput& aEvent) {
|
||||||
|
APZC_LOG("%p got a pan-cancelled in state %d\n", this, mState);
|
||||||
|
|
||||||
|
mX.CancelTouch();
|
||||||
|
mY.CancelTouch();
|
||||||
|
|
||||||
|
return nsEventStatus_eConsumeNoDefault;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
nsEventStatus AsyncPanZoomController::OnPanBegin(const PanGestureInput& aEvent) {
|
||||||
|
APZC_LOG("%p got a pan-begin in state %d\n", this, mState);
|
||||||
|
|
||||||
|
mX.StartTouch(aEvent.mPanStartPoint.x, aEvent.mTime);
|
||||||
|
mY.StartTouch(aEvent.mPanStartPoint.y, aEvent.mTime);
|
||||||
|
|
||||||
|
if (GetAxisLockMode() == FREE) {
|
||||||
|
SetState(PANNING);
|
||||||
|
return nsEventStatus_eConsumeNoDefault;
|
||||||
|
}
|
||||||
|
|
||||||
|
float dx = aEvent.mPanDisplacement.x, dy = aEvent.mPanDisplacement.y;
|
||||||
|
double angle = atan2(dy, dx); // range [-pi, pi]
|
||||||
|
angle = fabs(angle); // range [0, pi]
|
||||||
|
|
||||||
|
HandlePanning(angle);
|
||||||
|
|
||||||
|
return nsEventStatus_eConsumeNoDefault;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsEventStatus AsyncPanZoomController::OnPan(const PanGestureInput& aEvent, bool aFingersOnTouchpad) {
|
||||||
|
APZC_LOG("%p got a pan-pan in state %d\n", this, mState);
|
||||||
|
|
||||||
|
// We need to update the axis velocity in order to get a useful display port
|
||||||
|
// size and position. We need to do so even if this is a momentum pan (i.e.
|
||||||
|
// aFingersOnTouchpad == false); in that case the "with touch" part is not
|
||||||
|
// really appropriate, so we may want to rethink this at some point.
|
||||||
|
mX.UpdateWithTouchAtDevicePoint(aEvent.mPanStartPoint.x, aEvent.mTime);
|
||||||
|
mY.UpdateWithTouchAtDevicePoint(aEvent.mPanStartPoint.y, aEvent.mTime);
|
||||||
|
|
||||||
|
HandlePanningUpdate(aEvent.mPanDisplacement.x, aEvent.mPanDisplacement.y);
|
||||||
|
|
||||||
|
CallDispatchScroll(aEvent.mPanStartPoint, aEvent.mPanStartPoint + aEvent.mPanDisplacement, 0);
|
||||||
|
|
||||||
|
return nsEventStatus_eConsumeNoDefault;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsEventStatus AsyncPanZoomController::OnPanEnd(const PanGestureInput& aEvent) {
|
||||||
|
APZC_LOG("%p got a pan-end in state %d\n", this, mState);
|
||||||
|
|
||||||
|
mX.EndTouch(aEvent.mTime);
|
||||||
|
mY.EndTouch(aEvent.mTime);
|
||||||
|
RequestContentRepaint();
|
||||||
|
|
||||||
|
return nsEventStatus_eConsumeNoDefault;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsEventStatus AsyncPanZoomController::OnPanMomentumStart(const PanGestureInput& aEvent) {
|
||||||
|
APZC_LOG("%p got a pan-momentumstart in state %d\n", this, mState);
|
||||||
|
|
||||||
|
return nsEventStatus_eConsumeNoDefault;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsEventStatus AsyncPanZoomController::OnPanMomentumEnd(const PanGestureInput& aEvent) {
|
||||||
|
APZC_LOG("%p got a pan-momentumend in state %d\n", this, mState);
|
||||||
|
|
||||||
|
// We need to reset the velocity to zero. We don't really have a "touch"
|
||||||
|
// here because the touch has already ended long before the momentum
|
||||||
|
// animation started, but I guess it doesn't really matter for now.
|
||||||
|
mX.CancelTouch();
|
||||||
|
mY.CancelTouch();
|
||||||
|
|
||||||
|
RequestContentRepaint();
|
||||||
|
|
||||||
|
return nsEventStatus_eConsumeNoDefault;
|
||||||
|
}
|
||||||
|
|
||||||
nsEventStatus AsyncPanZoomController::OnLongPress(const TapGestureInput& aEvent) {
|
nsEventStatus AsyncPanZoomController::OnLongPress(const TapGestureInput& aEvent) {
|
||||||
APZC_LOG("%p got a long-press in state %d\n", this, mState);
|
APZC_LOG("%p got a long-press in state %d\n", this, mState);
|
||||||
nsRefPtr<GeckoContentController> controller = GetGeckoContentController();
|
nsRefPtr<GeckoContentController> controller = GetGeckoContentController();
|
||||||
|
@ -1214,6 +1337,7 @@ void AsyncPanZoomController::HandlePanningWithTouchAction(double aAngle, TouchBe
|
||||||
}
|
}
|
||||||
|
|
||||||
void AsyncPanZoomController::HandlePanning(double aAngle) {
|
void AsyncPanZoomController::HandlePanning(double aAngle) {
|
||||||
|
ReentrantMonitorAutoEnter lock(mMonitor);
|
||||||
if (!gfxPrefs::APZCrossSlideEnabled() && (!mX.CanScrollNow() || !mY.CanScrollNow())) {
|
if (!gfxPrefs::APZCrossSlideEnabled() && (!mX.CanScrollNow() || !mY.CanScrollNow())) {
|
||||||
SetState(PANNING);
|
SetState(PANNING);
|
||||||
} else if (IsCloseToHorizontal(aAngle, AXIS_LOCK_ANGLE)) {
|
} else if (IsCloseToHorizontal(aAngle, AXIS_LOCK_ANGLE)) {
|
||||||
|
@ -1237,6 +1361,31 @@ void AsyncPanZoomController::HandlePanning(double aAngle) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AsyncPanZoomController::HandlePanningUpdate(float aDX, float aDY) {
|
||||||
|
// If we're axis-locked, check if the user is trying to break the lock
|
||||||
|
if (GetAxisLockMode() == STICKY && !mPanDirRestricted) {
|
||||||
|
|
||||||
|
double angle = atan2(aDY, aDX); // range [-pi, pi]
|
||||||
|
angle = fabs(angle); // range [0, pi]
|
||||||
|
|
||||||
|
float breakThreshold = AXIS_BREAKOUT_THRESHOLD * APZCTreeManager::GetDPI();
|
||||||
|
|
||||||
|
if (fabs(aDX) > breakThreshold || fabs(aDY) > breakThreshold) {
|
||||||
|
if (mState == PANNING_LOCKED_X || mState == CROSS_SLIDING_X) {
|
||||||
|
if (!IsCloseToHorizontal(angle, AXIS_BREAKOUT_ANGLE)) {
|
||||||
|
mY.SetAxisLocked(false);
|
||||||
|
SetState(PANNING);
|
||||||
|
}
|
||||||
|
} else if (mState == PANNING_LOCKED_Y || mState == CROSS_SLIDING_Y) {
|
||||||
|
if (!IsCloseToVertical(angle, AXIS_BREAKOUT_ANGLE)) {
|
||||||
|
mX.SetAxisLocked(false);
|
||||||
|
SetState(PANNING);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
nsEventStatus AsyncPanZoomController::StartPanning(const MultiTouchInput& aEvent) {
|
nsEventStatus AsyncPanZoomController::StartPanning(const MultiTouchInput& aEvent) {
|
||||||
ReentrantMonitorAutoEnter lock(mMonitor);
|
ReentrantMonitorAutoEnter lock(mMonitor);
|
||||||
|
|
||||||
|
@ -1414,31 +1563,9 @@ void AsyncPanZoomController::TrackTouch(const MultiTouchInput& aEvent) {
|
||||||
ScreenIntPoint prevTouchPoint(mX.GetPos(), mY.GetPos());
|
ScreenIntPoint prevTouchPoint(mX.GetPos(), mY.GetPos());
|
||||||
ScreenIntPoint touchPoint = GetFirstTouchScreenPoint(aEvent);
|
ScreenIntPoint touchPoint = GetFirstTouchScreenPoint(aEvent);
|
||||||
|
|
||||||
// If we're axis-locked, check if the user is trying to break the lock
|
float dx = mX.PanDistance(touchPoint.x);
|
||||||
if (GetAxisLockMode() == STICKY && !mPanDirRestricted) {
|
float dy = mY.PanDistance(touchPoint.y);
|
||||||
ScreenIntPoint point = GetFirstTouchScreenPoint(aEvent);
|
HandlePanningUpdate(dx, dy);
|
||||||
float dx = mX.PanDistance(point.x);
|
|
||||||
float dy = mY.PanDistance(point.y);
|
|
||||||
|
|
||||||
double angle = atan2(dy, dx); // range [-pi, pi]
|
|
||||||
angle = fabs(angle); // range [0, pi]
|
|
||||||
|
|
||||||
float breakThreshold = AXIS_BREAKOUT_THRESHOLD * APZCTreeManager::GetDPI();
|
|
||||||
|
|
||||||
if (fabs(dx) > breakThreshold || fabs(dy) > breakThreshold) {
|
|
||||||
if (mState == PANNING_LOCKED_X || mState == CROSS_SLIDING_X) {
|
|
||||||
if (!IsCloseToHorizontal(angle, AXIS_BREAKOUT_ANGLE)) {
|
|
||||||
mY.SetAxisLocked(false);
|
|
||||||
SetState(PANNING);
|
|
||||||
}
|
|
||||||
} else if (mState == PANNING_LOCKED_Y || mState == CROSS_SLIDING_Y) {
|
|
||||||
if (!IsCloseToVertical(angle, AXIS_BREAKOUT_ANGLE)) {
|
|
||||||
mX.SetAxisLocked(false);
|
|
||||||
SetState(PANNING);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
UpdateWithTouchAtDevicePoint(aEvent);
|
UpdateWithTouchAtDevicePoint(aEvent);
|
||||||
|
|
||||||
|
@ -1466,8 +1593,14 @@ bool FlingAnimation::Sample(FrameMetrics& aFrameMetrics,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool shouldContinueFlingX = mApzc.mX.FlingApplyFrictionOrCancel(aDelta),
|
bool overscrolled = mApzc.IsOverscrolled();
|
||||||
shouldContinueFlingY = mApzc.mY.FlingApplyFrictionOrCancel(aDelta);
|
float friction = overscrolled ? gfxPrefs::APZOverscrollFlingFriction()
|
||||||
|
: gfxPrefs::APZFlingFriction();
|
||||||
|
float threshold = overscrolled ? gfxPrefs::APZOverscrollFlingStoppedThreshold()
|
||||||
|
: gfxPrefs::APZFlingStoppedThreshold();
|
||||||
|
|
||||||
|
bool shouldContinueFlingX = mApzc.mX.FlingApplyFrictionOrCancel(aDelta, friction, threshold),
|
||||||
|
shouldContinueFlingY = mApzc.mY.FlingApplyFrictionOrCancel(aDelta, friction, threshold);
|
||||||
// If we shouldn't continue the fling, let's just stop and repaint.
|
// If we shouldn't continue the fling, let's just stop and repaint.
|
||||||
if (!shouldContinueFlingX && !shouldContinueFlingY) {
|
if (!shouldContinueFlingX && !shouldContinueFlingY) {
|
||||||
// If we are in overscroll, schedule the snap-back animation that relieves it.
|
// If we are in overscroll, schedule the snap-back animation that relieves it.
|
||||||
|
@ -1821,15 +1954,11 @@ bool AsyncPanZoomController::UpdateAnimation(const TimeStamp& aSampleTime,
|
||||||
|
|
||||||
void AsyncPanZoomController::ApplyOverscrollEffect(ViewTransform* aTransform) const {
|
void AsyncPanZoomController::ApplyOverscrollEffect(ViewTransform* aTransform) const {
|
||||||
// The overscroll effect applied here is a combination of a translation in
|
// The overscroll effect applied here is a combination of a translation in
|
||||||
// the direction of overscroll, and shrinking in both directions. For
|
// the direction of overscroll, and shrinking in both directions.
|
||||||
// example, when overscrolling past the top of the page, the rectangle of
|
|
||||||
// content that filled the composition bounds will now fill a smaller
|
|
||||||
// rectangle at the bottom of the composition bounds, centred horizontally.
|
|
||||||
// The magnitude of the translation and the shrinking depends on the amount
|
|
||||||
// of the overscroll.
|
|
||||||
// With the effect applied, we can think of the composited region as being
|
// With the effect applied, we can think of the composited region as being
|
||||||
// made up of the following subregions.
|
// made up of the following subregions.
|
||||||
// (1) The shrunk content that used to fill the composited region.
|
// (1) The shrunk content (or a portion of it) that used to fill the
|
||||||
|
// composited region.
|
||||||
// (2) The space created along the axis that has overscroll. This space is
|
// (2) The space created along the axis that has overscroll. This space is
|
||||||
// blank, filled by the background color of the overscrolled content.
|
// blank, filled by the background color of the overscrolled content.
|
||||||
// TODO(botond): Implement handling of background color.
|
// TODO(botond): Implement handling of background color.
|
||||||
|
@ -1846,61 +1975,71 @@ void AsyncPanZoomController::ApplyOverscrollEffect(ViewTransform* aTransform) co
|
||||||
|
|
||||||
// The maximum proportion of the composition length which can become blank
|
// The maximum proportion of the composition length which can become blank
|
||||||
// space along an axis as we overscroll along that axis.
|
// space along an axis as we overscroll along that axis.
|
||||||
const float CLAMPING = 0.5;
|
const float kClamping = gfxPrefs::APZOverscrollClamping();
|
||||||
|
|
||||||
// The proportion of the composition length which will become blank space
|
// The proportion of the composition length which will become blank space
|
||||||
// along each axis as a result of overscroll along that axis. Since
|
// along each axis as a result of overscroll along that axis. Since
|
||||||
// Axis::ApplyResistance() keeps the magnitude of the overscroll in the range
|
// Axis::ApplyResistance() keeps the magnitude of the overscroll in the range
|
||||||
// [0, GetCompositionLength()], these scale factors should be in the range
|
// [0, GetCompositionLength()], these scale factors should be in the range
|
||||||
// [0, CLAMPING].
|
// [0, kClamping].
|
||||||
float spacePropX = CLAMPING * fabsf(mX.GetOverscroll()) / mX.GetCompositionLength();
|
float spacePropX = kClamping * fabsf(mX.GetOverscroll()) / mX.GetCompositionLength();
|
||||||
float spacePropY = CLAMPING * fabsf(mY.GetOverscroll()) / mY.GetCompositionLength();
|
float spacePropY = kClamping * fabsf(mY.GetOverscroll()) / mY.GetCompositionLength();
|
||||||
|
|
||||||
|
// The fraction of the proportions above which will become blank space along
|
||||||
|
// the _opposite_ axis as we zoom out as a result of overscroll along an axis.
|
||||||
|
// This creates a 3D effect, as in the layer were moving backward along a "z"
|
||||||
|
// axis.
|
||||||
|
const float kZEffect = gfxPrefs::APZOverscrollZEffect();
|
||||||
|
|
||||||
// The translation to apply for overscroll along the x axis.
|
// The translation to apply for overscroll along the x axis.
|
||||||
CSSPoint translationX;
|
CSSPoint translationX;
|
||||||
if (mX.GetOverscroll() < 0) {
|
if (mX.IsOverscrolled()) {
|
||||||
// Overscroll on left.
|
// Keep the content centred vertically as we zoom out.
|
||||||
// Keep content at the midpoint of the screen's right edge fixed.
|
translationX.y = (spacePropX * kZEffect * mY.GetCompositionLength()) / 2;
|
||||||
translationX.x = spacePropX * mX.GetCompositionLength();
|
|
||||||
translationX.y = (spacePropX * mY.GetCompositionLength()) / 2;
|
if (mX.GetOverscroll() < 0) {
|
||||||
} else if (mX.GetOverscroll() > 0) {
|
// Overscroll on left.
|
||||||
// Overscroll on right.
|
translationX.x = spacePropX * mX.GetCompositionLength();
|
||||||
// Keep content at the midpoint of the screen's left edge fixed.
|
} else {
|
||||||
translationX.y = (spacePropX * mY.GetCompositionLength()) / 2;
|
// Overscroll on right.
|
||||||
|
// Note that zooming out already moves the content at the right edge
|
||||||
|
// of the composition bounds to the left, but since the zooming is
|
||||||
|
// dampened by kZEffect, it doesn't take us as far as we want to go.
|
||||||
|
translationX.x = - (spacePropX * (1 - kZEffect) * mX.GetCompositionLength());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The translation to apply for overscroll along the y axis.
|
// The translation to apply for overscroll along the y axis.
|
||||||
CSSPoint translationY;
|
CSSPoint translationY;
|
||||||
if (mY.GetOverscroll() < 0) {
|
if (mY.IsOverscrolled()) {
|
||||||
// Overscroll at top.
|
// Keep the content centred horizontally as we zoom out.
|
||||||
// Keep content at the midpoint of the screen's bottom edge fixed.
|
translationY.x = (spacePropY * kZEffect * mX.GetCompositionLength()) / 2;
|
||||||
translationY.x = (spacePropY * mX.GetCompositionLength()) / 2;
|
|
||||||
translationY.y = spacePropY * mY.GetCompositionLength();
|
if (mY.GetOverscroll() < 0) {
|
||||||
} else if (mY.GetOverscroll() > 0) {
|
// Overscroll at top.
|
||||||
// Overscroll at bottom.
|
translationY.y = spacePropY * mY.GetCompositionLength();
|
||||||
// Keep content at the midpoint of the screen's top edge fixed.
|
} else {
|
||||||
translationY.x = (spacePropY * mX.GetCompositionLength()) / 2;
|
// Overscroll at bottom.
|
||||||
|
// Note that zooming out already moves the content at the bottom edge
|
||||||
|
// of the composition bounds up, but since the zooming is
|
||||||
|
// dampened by kZEffect, it doesn't take us as far as we want to go.
|
||||||
|
translationY.y = - (spacePropY * (1 - kZEffect) * mY.GetCompositionLength());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Combine the transformations along the two axes.
|
// Combine the transformations along the two axes.
|
||||||
// TODO(botond): This method of combination is imperfect, and results in a
|
float spaceProp = sqrtf(spacePropX * spacePropX + spacePropY * spacePropY);
|
||||||
// funny-looking snap-back animation when we have overscroll along both axes.
|
CSSPoint translation = translationX + translationY;
|
||||||
// We should fine-tune this.
|
|
||||||
float spaceProp = std::max(spacePropX, spacePropY);
|
|
||||||
CSSPoint translation(std::max(translationX.x, translationY.x),
|
|
||||||
std::max(translationX.y, translationY.y));
|
|
||||||
|
|
||||||
// The prpoportion of the composition length which will be taken up by the
|
float scale = 1 - (kZEffect * spaceProp);
|
||||||
// original content; this is the scale we will apply to the content.
|
|
||||||
float contentProp = 1 - spaceProp;
|
|
||||||
|
|
||||||
// In a ViewTransform, the translation is applied before the scale. We want
|
// In a ViewTransform, the translation is applied before the scale. We want
|
||||||
// to apply our translation after our scale, so we compensate for that here.
|
// to apply our translation after our scale, so we compensate for that here.
|
||||||
translation.x /= contentProp;
|
translation.x /= scale;
|
||||||
translation.y /= contentProp;
|
translation.y /= scale;
|
||||||
|
|
||||||
// Finally, apply the transformations.
|
// Finally, apply the transformations.
|
||||||
aTransform->mScale.scale *= contentProp;
|
aTransform->mScale.scale *= scale;
|
||||||
aTransform->mTranslation += translation * mFrameMetrics.LayersPixelsPerCSSPixel();
|
aTransform->mTranslation += translation * mFrameMetrics.LayersPixelsPerCSSPixel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1923,9 +2062,11 @@ bool AsyncPanZoomController::SampleContentTransformForFrame(const TimeStamp& aSa
|
||||||
aScrollOffset = mFrameMetrics.GetScrollOffset() * mFrameMetrics.GetZoom();
|
aScrollOffset = mFrameMetrics.GetScrollOffset() * mFrameMetrics.GetZoom();
|
||||||
*aNewTransform = GetCurrentAsyncTransform();
|
*aNewTransform = GetCurrentAsyncTransform();
|
||||||
|
|
||||||
// GetCurrentAsyncTransform() does not consider any overscroll we may have.
|
if (IsOverscrolled()) {
|
||||||
// Adjust the transform to account for that.
|
// GetCurrentAsyncTransform() does not consider any overscroll we may have.
|
||||||
ApplyOverscrollEffect(aNewTransform);
|
// Adjust the transform to account for that.
|
||||||
|
ApplyOverscrollEffect(aNewTransform);
|
||||||
|
}
|
||||||
|
|
||||||
LogRendertraceRect(GetGuid(), "viewport", "red",
|
LogRendertraceRect(GetGuid(), "viewport", "red",
|
||||||
CSSRect(mFrameMetrics.GetScrollOffset(),
|
CSSRect(mFrameMetrics.GetScrollOffset(),
|
||||||
|
|
|
@ -387,6 +387,17 @@ protected:
|
||||||
*/
|
*/
|
||||||
nsEventStatus OnScaleEnd(const PinchGestureInput& aEvent);
|
nsEventStatus OnScaleEnd(const PinchGestureInput& aEvent);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper methods for handling pan events.
|
||||||
|
*/
|
||||||
|
nsEventStatus OnPanMayBegin(const PanGestureInput& aEvent);
|
||||||
|
nsEventStatus OnPanCancelled(const PanGestureInput& aEvent);
|
||||||
|
nsEventStatus OnPanBegin(const PanGestureInput& aEvent);
|
||||||
|
nsEventStatus OnPan(const PanGestureInput& aEvent, bool aFingersOnTouchpad);
|
||||||
|
nsEventStatus OnPanEnd(const PanGestureInput& aEvent);
|
||||||
|
nsEventStatus OnPanMomentumStart(const PanGestureInput& aEvent);
|
||||||
|
nsEventStatus OnPanMomentumEnd(const PanGestureInput& aEvent);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper methods for long press gestures.
|
* Helper methods for long press gestures.
|
||||||
*/
|
*/
|
||||||
|
@ -471,6 +482,11 @@ protected:
|
||||||
*/
|
*/
|
||||||
void HandlePanning(double angle);
|
void HandlePanning(double angle);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the panning state and axis locks.
|
||||||
|
*/
|
||||||
|
void HandlePanningUpdate(float aDX, float aDY);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets up anything needed for panning. This takes us out of the "TOUCHING"
|
* Sets up anything needed for panning. This takes us out of the "TOUCHING"
|
||||||
* state and starts actually panning us.
|
* state and starts actually panning us.
|
||||||
|
|
|
@ -121,21 +121,27 @@ float Axis::GetOverscroll() const {
|
||||||
return mOverscroll;
|
return mOverscroll;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Axis::StartSnapBack() {
|
|
||||||
float initialSnapBackVelocity = gfxPrefs::APZSnapBackInitialVelocity();
|
|
||||||
if (mOverscroll > 0) {
|
|
||||||
mVelocity = -initialSnapBackVelocity;
|
|
||||||
} else {
|
|
||||||
mVelocity = initialSnapBackVelocity;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Axis::SampleSnapBack(const TimeDuration& aDelta) {
|
bool Axis::SampleSnapBack(const TimeDuration& aDelta) {
|
||||||
// Accelerate the snap-back as time goes on.
|
// Apply spring physics to the snap-back as time goes on.
|
||||||
// Note: this method of acceleration isn't perfectly smooth, as it assumes
|
// Note: this method of sampling isn't perfectly smooth, as it assumes
|
||||||
// a constant velocity over 'aDelta', instead of an accelerating velocity.
|
// a constant velocity over 'aDelta', instead of an accelerating velocity.
|
||||||
// (The way we applying friction to flings has the same issue.)
|
// (The way we applying friction to flings has the same issue.)
|
||||||
mVelocity *= pow(1.0f + gfxPrefs::APZSnapBackAcceleration(), float(aDelta.ToMilliseconds()));
|
// Hooke's law with damping:
|
||||||
|
// F = -kx - bv
|
||||||
|
// where
|
||||||
|
// k is a constant related to the stiffness of the spring
|
||||||
|
// The larger the constant, the stiffer the spring.
|
||||||
|
// x is the displacement of the end of the spring from its equilibrium
|
||||||
|
// In our scenario, it's the amount of overscroll on the axis.
|
||||||
|
// b is a constant that provides damping (friction)
|
||||||
|
// v is the velocity of the point at the end of the spring
|
||||||
|
// See http://gafferongames.com/game-physics/spring-physics/
|
||||||
|
const float kSpringStiffness = gfxPrefs::APZOverscrollSnapBackSpringStiffness();
|
||||||
|
const float kSpringFriction = gfxPrefs::APZOverscrollSnapBackSpringFriction();
|
||||||
|
const float kMass = gfxPrefs::APZOverscrollSnapBackMass();
|
||||||
|
float force = -1 * kSpringStiffness * mOverscroll - kSpringFriction * mVelocity;
|
||||||
|
float acceleration = force / kMass;
|
||||||
|
mVelocity += acceleration * aDelta.ToMilliseconds();
|
||||||
float screenDisplacement = mVelocity * aDelta.ToMilliseconds();
|
float screenDisplacement = mVelocity * aDelta.ToMilliseconds();
|
||||||
float cssDisplacement = screenDisplacement / GetFrameMetrics().GetZoom().scale;
|
float cssDisplacement = screenDisplacement / GetFrameMetrics().GetZoom().scale;
|
||||||
if (mOverscroll > 0) {
|
if (mOverscroll > 0) {
|
||||||
|
@ -210,15 +216,17 @@ bool Axis::CanScrollNow() const {
|
||||||
return !mAxisLocked && CanScroll();
|
return !mAxisLocked && CanScroll();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Axis::FlingApplyFrictionOrCancel(const TimeDuration& aDelta) {
|
bool Axis::FlingApplyFrictionOrCancel(const TimeDuration& aDelta,
|
||||||
if (fabsf(mVelocity) <= gfxPrefs::APZFlingStoppedThreshold()) {
|
float aFriction,
|
||||||
|
float aThreshold) {
|
||||||
|
if (fabsf(mVelocity) <= aThreshold) {
|
||||||
// If the velocity is very low, just set it to 0 and stop the fling,
|
// If the velocity is very low, just set it to 0 and stop the fling,
|
||||||
// otherwise we'll just asymptotically approach 0 and the user won't
|
// otherwise we'll just asymptotically approach 0 and the user won't
|
||||||
// actually see any changes.
|
// actually see any changes.
|
||||||
mVelocity = 0.0f;
|
mVelocity = 0.0f;
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
mVelocity *= pow(1.0f - gfxPrefs::APZFlingFriction(), float(aDelta.ToMilliseconds()));
|
mVelocity *= pow(1.0f - aFriction, float(aDelta.ToMilliseconds()));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,11 +98,6 @@ public:
|
||||||
*/
|
*/
|
||||||
float GetOverscroll() const;
|
float GetOverscroll() const;
|
||||||
|
|
||||||
/**
|
|
||||||
* Start a snap-back animation to relieve overscroll.
|
|
||||||
*/
|
|
||||||
void StartSnapBack();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sample the snap-back animation to relieve overscroll.
|
* Sample the snap-back animation to relieve overscroll.
|
||||||
* |aDelta| is the time since the last sample.
|
* |aDelta| is the time since the last sample.
|
||||||
|
@ -130,10 +125,15 @@ public:
|
||||||
/**
|
/**
|
||||||
* Applies friction during a fling, or cancels the fling if the velocity is
|
* Applies friction during a fling, or cancels the fling if the velocity is
|
||||||
* too low. Returns true if the fling should continue to another frame, or
|
* too low. Returns true if the fling should continue to another frame, or
|
||||||
* false if it should end. |aDelta| is the amount of time that has passed
|
* false if it should end.
|
||||||
* since the last time friction was applied.
|
* |aDelta| is the amount of time that has passed since the last time
|
||||||
|
* friction was applied.
|
||||||
|
* |aFriction| is the amount of friction to apply.
|
||||||
|
* |aThreshold| is the velocity below which the fling is cancelled.
|
||||||
*/
|
*/
|
||||||
bool FlingApplyFrictionOrCancel(const TimeDuration& aDelta);
|
bool FlingApplyFrictionOrCancel(const TimeDuration& aDelta,
|
||||||
|
float aFriction,
|
||||||
|
float aThreshold);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the page has room to be scrolled along this axis.
|
* Returns true if the page has room to be scrolled along this axis.
|
||||||
|
|
|
@ -309,7 +309,7 @@ EXPORTS.skia += [
|
||||||
'trunk/src/ports/SkMutex_pthread.h',
|
'trunk/src/ports/SkMutex_pthread.h',
|
||||||
'trunk/src/ports/SkMutex_win.h',
|
'trunk/src/ports/SkMutex_win.h',
|
||||||
]
|
]
|
||||||
SOURCES += [
|
UNIFIED_SOURCES += [
|
||||||
'trunk/src/core/SkAAClip.cpp',
|
'trunk/src/core/SkAAClip.cpp',
|
||||||
'trunk/src/core/SkAdvancedTypefaceMetrics.cpp',
|
'trunk/src/core/SkAdvancedTypefaceMetrics.cpp',
|
||||||
'trunk/src/core/SkAlphaRuns.cpp',
|
'trunk/src/core/SkAlphaRuns.cpp',
|
||||||
|
@ -323,16 +323,11 @@ SOURCES += [
|
||||||
'trunk/src/core/SkBitmapHeap.cpp',
|
'trunk/src/core/SkBitmapHeap.cpp',
|
||||||
'trunk/src/core/SkBitmapProcShader.cpp',
|
'trunk/src/core/SkBitmapProcShader.cpp',
|
||||||
'trunk/src/core/SkBitmapProcState.cpp',
|
'trunk/src/core/SkBitmapProcState.cpp',
|
||||||
'trunk/src/core/SkBitmapProcState_matrixProcs.cpp',
|
|
||||||
'trunk/src/core/SkBitmapScaler.cpp',
|
'trunk/src/core/SkBitmapScaler.cpp',
|
||||||
'trunk/src/core/SkBlitMask_D32.cpp',
|
'trunk/src/core/SkBlitMask_D32.cpp',
|
||||||
'trunk/src/core/SkBlitRow_D16.cpp',
|
'trunk/src/core/SkBlitRow_D16.cpp',
|
||||||
'trunk/src/core/SkBlitRow_D32.cpp',
|
'trunk/src/core/SkBlitRow_D32.cpp',
|
||||||
'trunk/src/core/SkBlitter.cpp',
|
'trunk/src/core/SkBlitter.cpp',
|
||||||
'trunk/src/core/SkBlitter_A8.cpp',
|
|
||||||
'trunk/src/core/SkBlitter_ARGB32.cpp',
|
|
||||||
'trunk/src/core/SkBlitter_RGB16.cpp',
|
|
||||||
'trunk/src/core/SkBlitter_Sprite.cpp',
|
|
||||||
'trunk/src/core/SkBuffer.cpp',
|
'trunk/src/core/SkBuffer.cpp',
|
||||||
'trunk/src/core/SkCanvas.cpp',
|
'trunk/src/core/SkCanvas.cpp',
|
||||||
'trunk/src/core/SkChunkAlloc.cpp',
|
'trunk/src/core/SkChunkAlloc.cpp',
|
||||||
|
@ -418,7 +413,6 @@ SOURCES += [
|
||||||
'trunk/src/core/SkScaledImageCache.cpp',
|
'trunk/src/core/SkScaledImageCache.cpp',
|
||||||
'trunk/src/core/SkScalerContext.cpp',
|
'trunk/src/core/SkScalerContext.cpp',
|
||||||
'trunk/src/core/SkScan.cpp',
|
'trunk/src/core/SkScan.cpp',
|
||||||
'trunk/src/core/SkScan_Antihair.cpp',
|
|
||||||
'trunk/src/core/SkScan_AntiPath.cpp',
|
'trunk/src/core/SkScan_AntiPath.cpp',
|
||||||
'trunk/src/core/SkScan_Hairline.cpp',
|
'trunk/src/core/SkScan_Hairline.cpp',
|
||||||
'trunk/src/core/SkScan_Path.cpp',
|
'trunk/src/core/SkScan_Path.cpp',
|
||||||
|
@ -553,7 +547,6 @@ SOURCES += [
|
||||||
'trunk/src/gpu/GrAAConvexPathRenderer.cpp',
|
'trunk/src/gpu/GrAAConvexPathRenderer.cpp',
|
||||||
'trunk/src/gpu/GrAAHairLinePathRenderer.cpp',
|
'trunk/src/gpu/GrAAHairLinePathRenderer.cpp',
|
||||||
'trunk/src/gpu/GrAARectRenderer.cpp',
|
'trunk/src/gpu/GrAARectRenderer.cpp',
|
||||||
'trunk/src/gpu/GrAddPathRenderers_default.cpp',
|
|
||||||
'trunk/src/gpu/GrAllocPool.cpp',
|
'trunk/src/gpu/GrAllocPool.cpp',
|
||||||
'trunk/src/gpu/GrAtlas.cpp',
|
'trunk/src/gpu/GrAtlas.cpp',
|
||||||
'trunk/src/gpu/GrBitmapTextContext.cpp',
|
'trunk/src/gpu/GrBitmapTextContext.cpp',
|
||||||
|
@ -565,7 +558,6 @@ SOURCES += [
|
||||||
'trunk/src/gpu/GrClipMaskManager.cpp',
|
'trunk/src/gpu/GrClipMaskManager.cpp',
|
||||||
'trunk/src/gpu/GrContext.cpp',
|
'trunk/src/gpu/GrContext.cpp',
|
||||||
'trunk/src/gpu/GrDefaultPathRenderer.cpp',
|
'trunk/src/gpu/GrDefaultPathRenderer.cpp',
|
||||||
'trunk/src/gpu/GrDistanceFieldTextContext.cpp',
|
|
||||||
'trunk/src/gpu/GrDrawState.cpp',
|
'trunk/src/gpu/GrDrawState.cpp',
|
||||||
'trunk/src/gpu/GrDrawTarget.cpp',
|
'trunk/src/gpu/GrDrawTarget.cpp',
|
||||||
'trunk/src/gpu/GrEffect.cpp',
|
'trunk/src/gpu/GrEffect.cpp',
|
||||||
|
@ -663,7 +655,6 @@ SOURCES += [
|
||||||
'trunk/src/utils/SkCamera.cpp',
|
'trunk/src/utils/SkCamera.cpp',
|
||||||
'trunk/src/utils/SkCanvasStack.cpp',
|
'trunk/src/utils/SkCanvasStack.cpp',
|
||||||
'trunk/src/utils/SkCanvasStateUtils.cpp',
|
'trunk/src/utils/SkCanvasStateUtils.cpp',
|
||||||
'trunk/src/utils/SkCondVar.cpp',
|
|
||||||
'trunk/src/utils/SkCountdown.cpp',
|
'trunk/src/utils/SkCountdown.cpp',
|
||||||
'trunk/src/utils/SkCubicInterval.cpp',
|
'trunk/src/utils/SkCubicInterval.cpp',
|
||||||
'trunk/src/utils/SkCullPoints.cpp',
|
'trunk/src/utils/SkCullPoints.cpp',
|
||||||
|
@ -681,7 +672,6 @@ SOURCES += [
|
||||||
'trunk/src/utils/SkNullCanvas.cpp',
|
'trunk/src/utils/SkNullCanvas.cpp',
|
||||||
'trunk/src/utils/SkNWayCanvas.cpp',
|
'trunk/src/utils/SkNWayCanvas.cpp',
|
||||||
'trunk/src/utils/SkOSFile.cpp',
|
'trunk/src/utils/SkOSFile.cpp',
|
||||||
'trunk/src/utils/SkParse.cpp',
|
|
||||||
'trunk/src/utils/SkParseColor.cpp',
|
'trunk/src/utils/SkParseColor.cpp',
|
||||||
'trunk/src/utils/SkParsePath.cpp',
|
'trunk/src/utils/SkParsePath.cpp',
|
||||||
'trunk/src/utils/SkPathUtils.cpp',
|
'trunk/src/utils/SkPathUtils.cpp',
|
||||||
|
@ -691,6 +681,18 @@ SOURCES += [
|
||||||
'trunk/src/utils/SkSHA1.cpp',
|
'trunk/src/utils/SkSHA1.cpp',
|
||||||
'trunk/src/utils/SkUnitMappers.cpp',
|
'trunk/src/utils/SkUnitMappers.cpp',
|
||||||
]
|
]
|
||||||
|
SOURCES += [
|
||||||
|
'trunk/src/core/SkBitmapProcState_matrixProcs.cpp',
|
||||||
|
'trunk/src/core/SkBlitter_A8.cpp',
|
||||||
|
'trunk/src/core/SkBlitter_ARGB32.cpp',
|
||||||
|
'trunk/src/core/SkBlitter_RGB16.cpp',
|
||||||
|
'trunk/src/core/SkBlitter_Sprite.cpp',
|
||||||
|
'trunk/src/core/SkScan_Antihair.cpp',
|
||||||
|
'trunk/src/gpu/GrAddPathRenderers_default.cpp',
|
||||||
|
'trunk/src/gpu/GrDistanceFieldTextContext.cpp',
|
||||||
|
'trunk/src/utils/SkCondVar.cpp',
|
||||||
|
'trunk/src/utils/SkParse.cpp',
|
||||||
|
]
|
||||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('android', 'gonk'):
|
if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('android', 'gonk'):
|
||||||
SOURCES += [
|
SOURCES += [
|
||||||
'trunk/src/images/SkImageRef_ashmem.cpp',
|
'trunk/src/images/SkImageRef_ashmem.cpp',
|
||||||
|
|
|
@ -0,0 +1,148 @@
|
||||||
|
# HG changeset patch
|
||||||
|
# Parent c8288d0c7a1544a590a0cac9c39397ac10c8a45b
|
||||||
|
Bug 974900 - Add missing include guards to Skia headers - r=gw280
|
||||||
|
|
||||||
|
diff --git a/gfx/skia/trunk/include/images/SkImages.h b/gfx/skia/trunk/include/images/SkImages.h
|
||||||
|
--- a/gfx/skia/trunk/include/images/SkImages.h
|
||||||
|
+++ b/gfx/skia/trunk/include/images/SkImages.h
|
||||||
|
@@ -1,14 +1,19 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012 Google Inc.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license that can be
|
||||||
|
* found in the LICENSE file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
+#ifndef SkImages_DEFINED
|
||||||
|
+#define SkImages_DEFINED
|
||||||
|
+
|
||||||
|
class SkImages {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Initializes flattenables in the images project.
|
||||||
|
*/
|
||||||
|
static void InitializeFlattenables();
|
||||||
|
};
|
||||||
|
+
|
||||||
|
+#endif
|
||||||
|
diff --git a/gfx/skia/trunk/src/core/SkConvolver.h b/gfx/skia/trunk/src/core/SkConvolver.h
|
||||||
|
--- a/gfx/skia/trunk/src/core/SkConvolver.h
|
||||||
|
+++ b/gfx/skia/trunk/src/core/SkConvolver.h
|
||||||
|
@@ -8,16 +8,18 @@
|
||||||
|
#include "SkSize.h"
|
||||||
|
#include "SkTypes.h"
|
||||||
|
#include "SkTArray.h"
|
||||||
|
|
||||||
|
// avoid confusion with Mac OS X's math library (Carbon)
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
#undef FloatToConvolutionFixed
|
||||||
|
#undef ConvolutionFixedToFloat
|
||||||
|
+#undef FloatToFixed
|
||||||
|
+#undef FixedToFloat
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Represents a filter in one dimension. Each output pixel has one entry in this
|
||||||
|
// object for the filter values contributing to it. You build up the filter
|
||||||
|
// list by calling AddFilter for each output pixel (in order).
|
||||||
|
//
|
||||||
|
// We do 2-dimensional convolution by first convolving each row by one
|
||||||
|
// SkConvolutionFilter1D, then convolving each column by another one.
|
||||||
|
diff --git a/gfx/skia/trunk/src/gpu/GrAAConvexPathRenderer.h b/gfx/skia/trunk/src/gpu/GrAAConvexPathRenderer.h
|
||||||
|
--- a/gfx/skia/trunk/src/gpu/GrAAConvexPathRenderer.h
|
||||||
|
+++ b/gfx/skia/trunk/src/gpu/GrAAConvexPathRenderer.h
|
||||||
|
@@ -3,24 +3,28 @@
|
||||||
|
* Copyright 2012 Google Inc.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license that can be
|
||||||
|
* found in the LICENSE file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "GrPathRenderer.h"
|
||||||
|
|
||||||
|
+#ifndef GrAAConvexPathRenderer_DEFINED
|
||||||
|
+#define GrAAConvexPathRenderer_DEFINED
|
||||||
|
|
||||||
|
class GrAAConvexPathRenderer : public GrPathRenderer {
|
||||||
|
public:
|
||||||
|
GrAAConvexPathRenderer();
|
||||||
|
|
||||||
|
virtual bool canDrawPath(const SkPath& path,
|
||||||
|
const SkStrokeRec& stroke,
|
||||||
|
const GrDrawTarget* target,
|
||||||
|
bool antiAlias) const SK_OVERRIDE;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual bool onDrawPath(const SkPath& path,
|
||||||
|
const SkStrokeRec& stroke,
|
||||||
|
GrDrawTarget* target,
|
||||||
|
bool antiAlias) SK_OVERRIDE;
|
||||||
|
};
|
||||||
|
+
|
||||||
|
+#endif
|
||||||
|
diff --git a/gfx/skia/trunk/src/gpu/GrReducedClip.h b/gfx/skia/trunk/src/gpu/GrReducedClip.h
|
||||||
|
--- a/gfx/skia/trunk/src/gpu/GrReducedClip.h
|
||||||
|
+++ b/gfx/skia/trunk/src/gpu/GrReducedClip.h
|
||||||
|
@@ -1,16 +1,19 @@
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2012 Google Inc.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license that can be
|
||||||
|
* found in the LICENSE file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
+#ifndef GrReducedClip_DEFINED
|
||||||
|
+#define GrReducedClip_DEFINED
|
||||||
|
+
|
||||||
|
#include "SkClipStack.h"
|
||||||
|
#include "SkTLList.h"
|
||||||
|
|
||||||
|
namespace GrReducedClip {
|
||||||
|
|
||||||
|
typedef SkTLList<SkClipStack::Element> ElementList;
|
||||||
|
|
||||||
|
enum InitialState {
|
||||||
|
@@ -36,8 +39,10 @@ SK_API void ReduceClipStack(const SkClip
|
||||||
|
const SkIRect& queryBounds,
|
||||||
|
ElementList* result,
|
||||||
|
int32_t* resultGenID,
|
||||||
|
InitialState* initialState,
|
||||||
|
SkIRect* tighterBounds = NULL,
|
||||||
|
bool* requiresAA = NULL);
|
||||||
|
|
||||||
|
} // namespace GrReducedClip
|
||||||
|
+
|
||||||
|
+#endif
|
||||||
|
diff --git a/gfx/skia/trunk/src/pathops/SkLineParameters.h b/gfx/skia/trunk/src/pathops/SkLineParameters.h
|
||||||
|
--- a/gfx/skia/trunk/src/pathops/SkLineParameters.h
|
||||||
|
+++ b/gfx/skia/trunk/src/pathops/SkLineParameters.h
|
||||||
|
@@ -1,14 +1,18 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012 Google Inc.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license that can be
|
||||||
|
* found in the LICENSE file.
|
||||||
|
*/
|
||||||
|
+
|
||||||
|
+#ifndef SkLineParameters_DEFINED
|
||||||
|
+#define SkLineParameters_DEFINED
|
||||||
|
+
|
||||||
|
#include "SkPathOpsCubic.h"
|
||||||
|
#include "SkPathOpsLine.h"
|
||||||
|
#include "SkPathOpsQuad.h"
|
||||||
|
|
||||||
|
// Sources
|
||||||
|
// computer-aided design - volume 22 number 9 november 1990 pp 538 - 549
|
||||||
|
// online at http://cagd.cs.byu.edu/~tom/papers/bezclip.pdf
|
||||||
|
|
||||||
|
@@ -164,8 +168,10 @@ public:
|
||||||
|
return -a;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
double a;
|
||||||
|
double b;
|
||||||
|
double c;
|
||||||
|
};
|
||||||
|
+
|
||||||
|
+#endif
|
|
@ -0,0 +1,27 @@
|
||||||
|
# HG changeset patch
|
||||||
|
# Parent b12f9a408740aa5fd93c296a7d41e1b5f54c1b20
|
||||||
|
Bug 974900 - #undef interface defined by windows headers - r=gw280
|
||||||
|
|
||||||
|
diff --git a/gfx/skia/trunk/src/gpu/gl/GrGLCaps.h b/gfx/skia/trunk/src/gpu/gl/GrGLCaps.h
|
||||||
|
--- a/gfx/skia/trunk/src/gpu/gl/GrGLCaps.h
|
||||||
|
+++ b/gfx/skia/trunk/src/gpu/gl/GrGLCaps.h
|
||||||
|
@@ -9,16 +9,19 @@
|
||||||
|
#ifndef GrGLCaps_DEFINED
|
||||||
|
#define GrGLCaps_DEFINED
|
||||||
|
|
||||||
|
#include "GrDrawTargetCaps.h"
|
||||||
|
#include "GrGLStencilBuffer.h"
|
||||||
|
#include "SkTArray.h"
|
||||||
|
#include "SkTDArray.h"
|
||||||
|
|
||||||
|
+// defined in Windows headers
|
||||||
|
+#undef interface
|
||||||
|
+
|
||||||
|
class GrGLContextInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores some capabilities of a GL context. Most are determined by the GL
|
||||||
|
* version and the extensions string. It also tracks formats that have passed
|
||||||
|
* the FBO completeness test.
|
||||||
|
*/
|
||||||
|
class GrGLCaps : public GrDrawTargetCaps {
|
|
@ -5,6 +5,9 @@
|
||||||
* found in the LICENSE file.
|
* found in the LICENSE file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef SkImages_DEFINED
|
||||||
|
#define SkImages_DEFINED
|
||||||
|
|
||||||
class SkImages {
|
class SkImages {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
|
@ -12,3 +15,5 @@ public:
|
||||||
*/
|
*/
|
||||||
static void InitializeFlattenables();
|
static void InitializeFlattenables();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче