mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-29 07:42:04 +00:00
Merge mozilla-central to b2g-inbound
This commit is contained in:
commit
dbc1d335ad
3
CLOBBER
3
CLOBBER
@ -22,4 +22,5 @@
|
||||
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
|
||||
# don't change CLOBBER for WebIDL changes any more.
|
||||
|
||||
Bug 1121297 - Converted VolatileBuffer's CPP tests to GTests
|
||||
Bug 1100184 - Lots of file moves from the /netwerk flattening and zero faith
|
||||
in the build system to properly handle them.
|
||||
|
@ -117,7 +117,7 @@ function checkDebuggerPort() {
|
||||
function initResponsiveDesign() {
|
||||
Cu.import('resource:///modules/devtools/responsivedesign.jsm');
|
||||
ResponsiveUIManager.on('on', function(event, {tab:tab}) {
|
||||
let responsive = tab.__responsiveUI;
|
||||
let responsive = ResponsiveUIManager.getResponsiveUIForTab(tab);
|
||||
let document = tab.ownerDocument;
|
||||
|
||||
// Only tweak reponsive mode for shell.html tabs.
|
||||
@ -137,7 +137,7 @@ function initResponsiveDesign() {
|
||||
}, true);
|
||||
|
||||
// Enable touch events
|
||||
browserWindow.gBrowser.selectedTab.__responsiveUI.enableTouch();
|
||||
responsive.enableTouch();
|
||||
});
|
||||
|
||||
// Automatically toggle responsive design mode
|
||||
|
@ -148,7 +148,8 @@ window.addEventListener('ContentStart', function() {
|
||||
let chromewidth = window.outerWidth - window.innerWidth;
|
||||
let chromeheight = window.outerHeight - window.innerHeight + controlsHeight;
|
||||
if (isMulet) {
|
||||
let responsive = browserWindow.gBrowser.selectedTab.__responsiveUI;
|
||||
let tab = browserWindow.gBrowser.selectedTab;
|
||||
let responsive = ResponsiveUIManager.getResponsiveUIForTab(tab);
|
||||
responsive.setSize((Math.round(width * scale) + 16*2),
|
||||
(Math.round(height * scale) + controlsHeight + 61));
|
||||
} else {
|
||||
|
@ -29,6 +29,7 @@ int main(int argc, char* argv[], char* envp[]){
|
||||
}
|
||||
full_profile_path = (char*) malloc(strlen(cwd) + strlen(GAIA_PATH) + 2);
|
||||
if (!full_profile_path) {
|
||||
free(full_path);
|
||||
error(NOMEM);
|
||||
return -2;
|
||||
}
|
||||
|
@ -260,6 +260,7 @@ let MozLoopServiceInternal = {
|
||||
*/
|
||||
setError: function(errorType, error, actionCallback = null) {
|
||||
log.debug("setError", errorType, error);
|
||||
log.trace();
|
||||
let messageString, detailsString, detailsButtonLabelString, detailsButtonCallback;
|
||||
const NETWORK_ERRORS = [
|
||||
Cr.NS_ERROR_CONNECTION_REFUSED,
|
||||
@ -300,15 +301,24 @@ let MozLoopServiceInternal = {
|
||||
}
|
||||
|
||||
error.friendlyMessage = this.localizedStrings.get(messageString);
|
||||
error.friendlyDetails = detailsString ?
|
||||
this.localizedStrings.get(detailsString) :
|
||||
null;
|
||||
|
||||
// Default to the generic "retry_button" text even though the button won't be shown if
|
||||
// error.friendlyDetails is null.
|
||||
error.friendlyDetailsButtonLabel = detailsButtonLabelString ?
|
||||
this.localizedStrings.get(detailsButtonLabelString) :
|
||||
null;
|
||||
this.localizedStrings.get("retry_button");
|
||||
|
||||
error.friendlyDetailsButtonCallback = actionCallback || detailsButtonCallback || null;
|
||||
|
||||
if (detailsString) {
|
||||
error.friendlyDetails = this.localizedStrings.get(detailsString);
|
||||
} else if (error.friendlyDetailsButtonCallback) {
|
||||
// If we have a retry callback but no details use the generic try again string.
|
||||
error.friendlyDetails = this.localizedStrings.get("generic_failure_no_reason2");
|
||||
} else {
|
||||
error.friendlyDetails = null;
|
||||
}
|
||||
|
||||
gErrors.set(errorType, error);
|
||||
this.notifyStatusChanged();
|
||||
},
|
||||
@ -1219,7 +1229,8 @@ this.MozLoopService = {
|
||||
deferredInitialization.resolve("initialized to logged-in status");
|
||||
}, error => {
|
||||
log.debug("MozLoopService: error logging in using cached auth token");
|
||||
MozLoopServiceInternal.setError("login", error);
|
||||
let retryFunc = () => MozLoopServiceInternal.promiseRegisteredWithServers(LOOP_SESSION_TYPE.FXA);
|
||||
MozLoopServiceInternal.setError("login", error, retryFunc);
|
||||
deferredInitialization.reject("error logging in using cached auth token");
|
||||
});
|
||||
yield completedPromise;
|
||||
@ -1421,27 +1432,17 @@ this.MozLoopService = {
|
||||
MozLoopServiceInternal.clearError("profile");
|
||||
return MozLoopServiceInternal.fxAOAuthTokenData;
|
||||
});
|
||||
}).then(tokenData => {
|
||||
let client = new FxAccountsProfileClient({
|
||||
serverURL: gFxAOAuthClient.parameters.profile_uri,
|
||||
token: tokenData.access_token
|
||||
});
|
||||
client.fetchProfile().then(result => {
|
||||
MozLoopServiceInternal.fxAOAuthProfile = result;
|
||||
}, error => {
|
||||
log.error("Failed to retrieve profile", error);
|
||||
this.setError("profile", error);
|
||||
MozLoopServiceInternal.fxAOAuthProfile = null;
|
||||
MozLoopServiceInternal.notifyStatusChanged();
|
||||
});
|
||||
}).then(Task.async(function* fetchProfile(tokenData) {
|
||||
yield MozLoopService.fetchFxAProfile(tokenData);
|
||||
return tokenData;
|
||||
}).catch(error => {
|
||||
})).catch(error => {
|
||||
MozLoopServiceInternal.fxAOAuthTokenData = null;
|
||||
MozLoopServiceInternal.fxAOAuthProfile = null;
|
||||
MozLoopServiceInternal.deferredRegistrations.delete(LOOP_SESSION_TYPE.FXA);
|
||||
throw error;
|
||||
}).catch((error) => {
|
||||
MozLoopServiceInternal.setError("login", error);
|
||||
MozLoopServiceInternal.setError("login", error,
|
||||
() => MozLoopService.logInToFxA());
|
||||
// Re-throw for testing
|
||||
throw error;
|
||||
});
|
||||
@ -1485,6 +1486,30 @@ this.MozLoopService = {
|
||||
}
|
||||
}),
|
||||
|
||||
/**
|
||||
* Fetch/update the FxA Profile for the logged in user.
|
||||
*
|
||||
* @return {Promise} resolving if the profile information was succesfully retrieved
|
||||
* rejecting if the profile information couldn't be retrieved.
|
||||
* A profile error is registered.
|
||||
**/
|
||||
fetchFxAProfile: function() {
|
||||
log.debug("fetchFxAProfile");
|
||||
let client = new FxAccountsProfileClient({
|
||||
serverURL: gFxAOAuthClient.parameters.profile_uri,
|
||||
token: MozLoopServiceInternal.fxAOAuthTokenData.access_token
|
||||
});
|
||||
return client.fetchProfile().then(result => {
|
||||
MozLoopServiceInternal.fxAOAuthProfile = result;
|
||||
MozLoopServiceInternal.clearError("profile");
|
||||
}, error => {
|
||||
log.error("Failed to retrieve profile", error, this.fetchFxAProfile.bind(this));
|
||||
MozLoopServiceInternal.setError("profile", error);
|
||||
MozLoopServiceInternal.fxAOAuthProfile = null;
|
||||
MozLoopServiceInternal.notifyStatusChanged();
|
||||
});
|
||||
},
|
||||
|
||||
openFxASettings: Task.async(function() {
|
||||
try {
|
||||
let fxAOAuthClient = yield MozLoopServiceInternal.promiseFxAOAuthClient();
|
||||
|
@ -296,8 +296,9 @@ add_task(function* basicAuthorizationAndRegistration() {
|
||||
is(loopButton.getAttribute("state"), "", "state of loop button should be empty when not logged in");
|
||||
|
||||
info("Login");
|
||||
statusChangedPromise = promiseObserverNotified("loop-status-changed", "login");
|
||||
let tokenData = yield MozLoopService.logInToFxA();
|
||||
yield promiseObserverNotified("loop-status-changed", "login");
|
||||
yield statusChangedPromise;
|
||||
ise(tokenData.access_token, "code1_access_token", "Check access_token");
|
||||
ise(tokenData.scope, "profile", "Check scope");
|
||||
ise(tokenData.token_type, "bearer", "Check token_type");
|
||||
|
@ -74,7 +74,6 @@ add_task(function* guest_401() {
|
||||
Assert.strictEqual(err.code, 401);
|
||||
Assert.strictEqual(err.friendlyMessage, getLoopString("session_expired_error_description"));
|
||||
Assert.equal(err.friendlyDetails, null);
|
||||
Assert.equal(err.friendlyDetailsButtonLabel, null);
|
||||
});
|
||||
});
|
||||
|
||||
@ -115,7 +114,6 @@ add_task(function* error_404() {
|
||||
Assert.strictEqual(err.code, 404);
|
||||
Assert.strictEqual(err.friendlyMessage, getLoopString("generic_failure_title"));
|
||||
Assert.equal(err.friendlyDetails, null);
|
||||
Assert.equal(err.friendlyDetailsButtonLabel, null);
|
||||
});
|
||||
});
|
||||
|
||||
@ -149,7 +147,6 @@ add_task(function* profile_500() {
|
||||
Assert.strictEqual(err.code, 500);
|
||||
Assert.strictEqual(err.friendlyMessage, getLoopString("problem_accessing_account"));
|
||||
Assert.equal(err.friendlyDetails, null);
|
||||
Assert.equal(err.friendlyDetailsButtonLabel, null);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -77,6 +77,9 @@ add_task(function test_initialize_with_invalid_fxa_token() {
|
||||
"FXA profile pref should be cleared if token was invalid");
|
||||
Assert.ok(MozLoopServiceInternal.errors.has("login"),
|
||||
"Initialization error should have been reported to UI");
|
||||
Assert.ok(MozLoopServiceInternal.errors.has("login"));
|
||||
Assert.ok(MozLoopServiceInternal.errors.get("login").friendlyDetailsButtonCallback,
|
||||
"Check that there is a retry callback");
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -1038,7 +1038,7 @@ PlacesToolbar.prototype = {
|
||||
else {
|
||||
button = document.createElement("toolbarbutton");
|
||||
button.className = "bookmark-item";
|
||||
button.setAttribute("label", aChild.title);
|
||||
button.setAttribute("label", aChild.title || "");
|
||||
let icon = aChild.icon;
|
||||
if (icon)
|
||||
button.setAttribute("image",
|
||||
@ -1866,7 +1866,7 @@ PlacesPanelMenuView.prototype = {
|
||||
button.className = "bookmark-item";
|
||||
if (typeof this.options.extraClasses.entry == "string")
|
||||
button.classList.add(this.options.extraClasses.entry);
|
||||
button.setAttribute("label", aChild.title);
|
||||
button.setAttribute("label", aChild.title || "");
|
||||
let icon = aChild.icon;
|
||||
if (icon)
|
||||
button.setAttribute("image",
|
||||
|
@ -4,7 +4,8 @@
|
||||
|
||||
EXTRA_JS_MODULES.devtools += [
|
||||
'resize-commands.js',
|
||||
'responsivedesign.jsm',
|
||||
'responsivedesign-child.js',
|
||||
'responsivedesign.jsm'
|
||||
]
|
||||
|
||||
BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
|
||||
|
129
browser/devtools/responsivedesign/responsivedesign-child.js
Normal file
129
browser/devtools/responsivedesign/responsivedesign-child.js
Normal file
@ -0,0 +1,129 @@
|
||||
/* 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/. */
|
||||
|
||||
const Ci = Components.interfaces;
|
||||
const gDeviceSizeWasPageSize = docShell.deviceSizeIsPageSize;
|
||||
const gFloatingScrollbarsStylesheet = Services.io.newURI("chrome://browser/skin/devtools/floating-scrollbars.css", null, null);
|
||||
let gRequiresFloatingScrollbars;
|
||||
|
||||
let active = false;
|
||||
|
||||
addMessageListener("ResponsiveMode:Start", startResponsiveMode);
|
||||
addMessageListener("ResponsiveMode:Stop", stopResponsiveMode);
|
||||
|
||||
function startResponsiveMode({data:data}) {
|
||||
if (active) {
|
||||
return;
|
||||
}
|
||||
addMessageListener("ResponsiveMode:RequestScreenshot", screenshot);
|
||||
addMessageListener("ResponsiveMode:NotifyOnResize", notifiyOnResize);
|
||||
let webProgress = docShell.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebProgress);
|
||||
webProgress.addProgressListener(WebProgressListener, Ci.nsIWebProgress.NOTIFY_ALL);
|
||||
docShell.deviceSizeIsPageSize = true;
|
||||
gRequiresFloatingScrollbars = data.requiresFloatingScrollbars;
|
||||
|
||||
// At this point, a content viewer might not be loaded for this
|
||||
// docshell. makeScrollbarsFloating will be triggered by onLocationChange.
|
||||
if (docShell.contentViewer) {
|
||||
makeScrollbarsFloating();
|
||||
}
|
||||
active = true;
|
||||
sendAsyncMessage("ResponsiveMode:Start:Done");
|
||||
}
|
||||
|
||||
function notifiyOnResize() {
|
||||
content.addEventListener("resize", () => {
|
||||
sendAsyncMessage("ResponsiveMode:OnContentResize");
|
||||
}, false);
|
||||
sendAsyncMessage("ResponsiveMode:NotifyOnResize:Done");
|
||||
}
|
||||
|
||||
function stopResponsiveMode() {
|
||||
if (!active) {
|
||||
return;
|
||||
}
|
||||
active = false;
|
||||
removeMessageListener("ResponsiveMode:RequestScreenshot", screenshot);
|
||||
removeMessageListener("ResponsiveMode:NotifyOnResize", notifiyOnResize);
|
||||
let webProgress = docShell.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebProgress);
|
||||
webProgress.removeProgressListener(WebProgressListener);
|
||||
docShell.deviceSizeIsPageSize = gDeviceSizeWasPageSize;
|
||||
restoreScrollbars();
|
||||
sendAsyncMessage("ResponsiveMode:Stop:Done");
|
||||
}
|
||||
|
||||
function makeScrollbarsFloating() {
|
||||
if (!gRequiresFloatingScrollbars) {
|
||||
return;
|
||||
}
|
||||
|
||||
let allDocShells = [docShell];
|
||||
|
||||
for (let i = 0; i < docShell.childCount; i++) {
|
||||
let child = docShell.getChildAt(i).QueryInterface(Ci.nsIDocShell);
|
||||
allDocShells.push(child);
|
||||
}
|
||||
|
||||
for (let d of allDocShells) {
|
||||
let win = d.contentViewer.DOMDocument.defaultView;
|
||||
let winUtils = win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
|
||||
try {
|
||||
winUtils.loadSheet(gFloatingScrollbarsStylesheet, win.AGENT_SHEET);
|
||||
} catch(e) { }
|
||||
}
|
||||
|
||||
flushStyle();
|
||||
}
|
||||
|
||||
function restoreScrollbars() {
|
||||
let allDocShells = [docShell];
|
||||
for (let i = 0; i < docShell.childCount; i++) {
|
||||
allDocShells.push(docShell.getChildAt(i).QueryInterface(Ci.nsIDocShell));
|
||||
}
|
||||
for (let d of allDocShells) {
|
||||
let win = d.contentViewer.DOMDocument.defaultView;
|
||||
let winUtils = win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
|
||||
try {
|
||||
winUtils.removeSheet(gFloatingScrollbarsStylesheet, win.AGENT_SHEET);
|
||||
} catch(e) { }
|
||||
}
|
||||
flushStyle();
|
||||
}
|
||||
|
||||
function flushStyle() {
|
||||
// Force presContext destruction
|
||||
let isSticky = docShell.contentViewer.sticky;
|
||||
docShell.contentViewer.sticky = false;
|
||||
docShell.contentViewer.hide();
|
||||
docShell.contentViewer.show();
|
||||
docShell.contentViewer.sticky = isSticky;
|
||||
}
|
||||
|
||||
function screenshot() {
|
||||
let canvas = content.document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
|
||||
let width = content.innerWidth;
|
||||
let height = content.innerHeight;
|
||||
canvas.mozOpaque = true;
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
let ctx = canvas.getContext("2d");
|
||||
ctx.drawWindow(content, content.scrollX, content.scrollY, width, height, "#fff");
|
||||
sendAsyncMessage("ResponsiveMode:RequestScreenshot:Done", canvas.toDataURL());
|
||||
}
|
||||
|
||||
let WebProgressListener = {
|
||||
onLocationChange: function onLocationChange(aWebProgress) {
|
||||
makeScrollbarsFloating();
|
||||
},
|
||||
QueryInterface: function QueryInterface(aIID) {
|
||||
if (aIID.equals(Ci.nsIWebProgressListener) ||
|
||||
aIID.equals(Ci.nsISupportsWeakReference) ||
|
||||
aIID.equals(Ci.nsISupports)) {
|
||||
return this;
|
||||
}
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
};
|
||||
|
||||
sendAsyncMessage("ResponsiveMode:ChildScriptReady");
|
@ -10,8 +10,8 @@ const Cu = Components.utils;
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource:///modules/devtools/gDevTools.jsm");
|
||||
Cu.import("resource:///modules/devtools/FloatingScrollbars.jsm");
|
||||
Cu.import("resource://gre/modules/devtools/event-emitter.js");
|
||||
let { Promise: promise } = Cu.import("resource://gre/modules/Promise.jsm", {});
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy",
|
||||
"resource://gre/modules/SystemAppProxy.jsm");
|
||||
|
||||
@ -33,6 +33,8 @@ const ROUND_RATIO = 10;
|
||||
|
||||
const INPUT_PARSER = /(\d+)[^\d]+(\d+)/;
|
||||
|
||||
let ActiveTabs = new Map();
|
||||
|
||||
this.ResponsiveUIManager = {
|
||||
/**
|
||||
* Check if the a tab is in a responsive mode.
|
||||
@ -43,8 +45,8 @@ this.ResponsiveUIManager = {
|
||||
* @param aTab the tab targeted.
|
||||
*/
|
||||
toggle: function(aWindow, aTab) {
|
||||
if (aTab.__responsiveUI) {
|
||||
aTab.__responsiveUI.close();
|
||||
if (this.isActiveForTab(aTab)) {
|
||||
ActiveTabs.get(aTab).close();
|
||||
} else {
|
||||
new ResponsiveUI(aWindow, aTab);
|
||||
}
|
||||
@ -56,7 +58,14 @@ this.ResponsiveUIManager = {
|
||||
* @param aTab the tab targeted.
|
||||
*/
|
||||
isActiveForTab: function(aTab) {
|
||||
return !!aTab.__responsiveUI;
|
||||
return ActiveTabs.has(aTab);
|
||||
},
|
||||
|
||||
/**
|
||||
* Return the responsive UI controller for a tab.
|
||||
*/
|
||||
getResponsiveUIForTab: function(aTab) {
|
||||
return ActiveTabs.get(aTab);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -70,19 +79,19 @@ this.ResponsiveUIManager = {
|
||||
handleGcliCommand: function(aWindow, aTab, aCommand, aArgs) {
|
||||
switch (aCommand) {
|
||||
case "resize to":
|
||||
if (!aTab.__responsiveUI) {
|
||||
if (!this.isActiveForTab(aTab)) {
|
||||
new ResponsiveUI(aWindow, aTab);
|
||||
}
|
||||
aTab.__responsiveUI.setSize(aArgs.width, aArgs.height);
|
||||
ActiveTabs.get(aTab).setSize(aArgs.width, aArgs.height);
|
||||
break;
|
||||
case "resize on":
|
||||
if (!aTab.__responsiveUI) {
|
||||
if (!this.isActiveForTab(aTab)) {
|
||||
new ResponsiveUI(aWindow, aTab);
|
||||
}
|
||||
break;
|
||||
case "resize off":
|
||||
if (aTab.__responsiveUI) {
|
||||
aTab.__responsiveUI.close();
|
||||
if (this.isActiveForTab(aTab)) {
|
||||
ActiveTabs.get(aTab).close();
|
||||
}
|
||||
break;
|
||||
case "resize toggle":
|
||||
@ -115,13 +124,28 @@ function ResponsiveUI(aWindow, aTab)
|
||||
{
|
||||
this.mainWindow = aWindow;
|
||||
this.tab = aTab;
|
||||
this.mm = this.tab.linkedBrowser.messageManager;
|
||||
this.tabContainer = aWindow.gBrowser.tabContainer;
|
||||
this.browser = aTab.linkedBrowser;
|
||||
this.chromeDoc = aWindow.document;
|
||||
this.container = aWindow.gBrowser.getBrowserContainer(this.browser);
|
||||
this.stack = this.container.querySelector(".browserStack");
|
||||
this._telemetry = new Telemetry();
|
||||
this._floatingScrollbars = !this.mainWindow.matchMedia("(-moz-overlay-scrollbars)").matches;
|
||||
this.e10s = !this.browser.contentWindow;
|
||||
|
||||
let childOn = () => {
|
||||
this.mm.removeMessageListener("ResponsiveMode:Start:Done", childOn);
|
||||
ResponsiveUIManager.emit("on", { tab: this.tab });
|
||||
}
|
||||
this.mm.addMessageListener("ResponsiveMode:Start:Done", childOn);
|
||||
|
||||
let requiresFloatingScrollbars = !this.mainWindow.matchMedia("(-moz-overlay-scrollbars)").matches;
|
||||
this.mm.loadFrameScript("resource:///modules/devtools/responsivedesign-child.js", true);
|
||||
this.mm.addMessageListener("ResponsiveMode:ChildScriptReady", () => {
|
||||
this.mm.sendAsyncMessage("ResponsiveMode:Start", {
|
||||
requiresFloatingScrollbars: requiresFloatingScrollbars
|
||||
});
|
||||
});
|
||||
|
||||
// Try to load presets from prefs
|
||||
if (Services.prefs.prefHasUserValue("devtools.responsiveUI.presets")) {
|
||||
@ -163,8 +187,6 @@ function ResponsiveUI(aWindow, aTab)
|
||||
this.stack.setAttribute("responsivemode", "true");
|
||||
|
||||
// Let's bind some callbacks.
|
||||
this.bound_onPageLoad = this.onPageLoad.bind(this);
|
||||
this.bound_onPageUnload = this.onPageUnload.bind(this);
|
||||
this.bound_presetSelected = this.presetSelected.bind(this);
|
||||
this.bound_handleManualInput = this.handleManualInput.bind(this);
|
||||
this.bound_addPreset = this.addPreset.bind(this);
|
||||
@ -184,41 +206,22 @@ function ResponsiveUI(aWindow, aTab)
|
||||
this.buildUI();
|
||||
this.checkMenus();
|
||||
|
||||
this.docShell = this.browser.contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.QueryInterface(Ci.nsIDocShell);
|
||||
|
||||
this._deviceSizeWasPageSize = this.docShell.deviceSizeIsPageSize;
|
||||
this.docShell.deviceSizeIsPageSize = true;
|
||||
|
||||
try {
|
||||
if (Services.prefs.getBoolPref("devtools.responsiveUI.rotate")) {
|
||||
this.rotate();
|
||||
}
|
||||
} catch(e) {}
|
||||
|
||||
if (this._floatingScrollbars)
|
||||
switchToFloatingScrollbars(this.tab);
|
||||
|
||||
this.tab.__responsiveUI = this;
|
||||
ActiveTabs.set(aTab, this);
|
||||
|
||||
this._telemetry.toolOpened("responsive");
|
||||
|
||||
// Touch events support
|
||||
this.touchEnableBefore = false;
|
||||
this.touchEventHandler = new TouchEventHandler(this.browser);
|
||||
|
||||
this.browser.addEventListener("load", this.bound_onPageLoad, true);
|
||||
this.browser.addEventListener("unload", this.bound_onPageUnload, true);
|
||||
|
||||
if (this.browser.contentWindow.document &&
|
||||
this.browser.contentWindow.document.readyState == "complete") {
|
||||
this.onPageLoad();
|
||||
if (!this.e10s) {
|
||||
// Touch events support
|
||||
this.touchEnableBefore = false;
|
||||
this.touchEventHandler = new TouchEventHandler(this.browser);
|
||||
}
|
||||
|
||||
// E10S: We should be using target here. See bug 1028234
|
||||
ResponsiveUIManager.emit("on", { tab: this.tab });
|
||||
|
||||
// Hook to display promotional Developer Edition doorhanger. Only displayed once.
|
||||
showDoorhanger({
|
||||
window: this.mainWindow,
|
||||
@ -239,45 +242,14 @@ ResponsiveUI.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Window onload / onunload
|
||||
*/
|
||||
onPageLoad: function() {
|
||||
this.touchEventHandler = new TouchEventHandler(this.browser);
|
||||
if (this.touchEnableBefore) {
|
||||
this.enableTouch();
|
||||
}
|
||||
},
|
||||
|
||||
onPageUnload: function(evt) {
|
||||
// Ignore sub frames unload events
|
||||
if (evt.target != this.browser.contentDocument)
|
||||
return;
|
||||
if (this.closing)
|
||||
return;
|
||||
if (this.touchEventHandler) {
|
||||
this.touchEnableBefore = this.touchEventHandler.enabled;
|
||||
this.disableTouch();
|
||||
delete this.touchEventHandler;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Destroy the nodes. Remove listeners. Reset the style.
|
||||
*/
|
||||
close: function RUI_unload() {
|
||||
close: function RUI_close() {
|
||||
if (this.closing)
|
||||
return;
|
||||
this.closing = true;
|
||||
|
||||
this.docShell.deviceSizeIsPageSize = this._deviceSizeWasPageSize;
|
||||
|
||||
this.browser.removeEventListener("load", this.bound_onPageLoad, true);
|
||||
this.browser.removeEventListener("unload", this.bound_onPageUnload, true);
|
||||
|
||||
if (this._floatingScrollbars)
|
||||
switchToNativeScrollbars(this.tab);
|
||||
|
||||
this.unCheckMenus();
|
||||
// Reset style of the stack.
|
||||
let style = "max-width: none;" +
|
||||
@ -296,10 +268,12 @@ ResponsiveUI.prototype = {
|
||||
this.tabContainer.removeEventListener("TabSelect", this);
|
||||
this.rotatebutton.removeEventListener("command", this.bound_rotate, true);
|
||||
this.screenshotbutton.removeEventListener("command", this.bound_screenshot, true);
|
||||
this.touchbutton.removeEventListener("command", this.bound_touch, true);
|
||||
this.closebutton.removeEventListener("command", this.bound_close, true);
|
||||
this.addbutton.removeEventListener("command", this.bound_addPreset, true);
|
||||
this.removebutton.removeEventListener("command", this.bound_removePreset, true);
|
||||
if (!this.e10s) {
|
||||
this.touchbutton.removeEventListener("command", this.bound_touch, true);
|
||||
}
|
||||
|
||||
// Removed elements.
|
||||
this.container.removeChild(this.toolbar);
|
||||
@ -317,13 +291,40 @@ ResponsiveUI.prototype = {
|
||||
this.container.removeAttribute("responsivemode");
|
||||
this.stack.removeAttribute("responsivemode");
|
||||
|
||||
delete this.docShell;
|
||||
delete this.tab.__responsiveUI;
|
||||
if (this.touchEventHandler)
|
||||
ActiveTabs.delete(this.tab);
|
||||
if (!this.e10s && this.touchEventHandler) {
|
||||
this.touchEventHandler.stop();
|
||||
}
|
||||
this._telemetry.toolClosed("responsive");
|
||||
// E10S: We should be using target here. See bug 1028234
|
||||
ResponsiveUIManager.emit("off", { tab: this.tab });
|
||||
let childOff = () => {
|
||||
this.mm.removeMessageListener("ResponsiveMode:Stop:Done", childOff);
|
||||
ResponsiveUIManager.emit("off", { tab: this.tab });
|
||||
}
|
||||
this.mm.addMessageListener("ResponsiveMode:Stop:Done", childOff);
|
||||
this.tab.linkedBrowser.messageManager.sendAsyncMessage("ResponsiveMode:Stop");
|
||||
},
|
||||
|
||||
/**
|
||||
* Notify when the content has been resized. Only used in tests.
|
||||
*/
|
||||
_test_notifyOnResize: function() {
|
||||
let deferred = promise.defer();
|
||||
let mm = this.mm;
|
||||
|
||||
this.bound_onContentResize = this.onContentResize.bind(this);
|
||||
|
||||
mm.addMessageListener("ResponsiveMode:OnContentResize", this.bound_onContentResize);
|
||||
|
||||
mm.sendAsyncMessage("ResponsiveMode:NotifyOnResize");
|
||||
mm.addMessageListener("ResponsiveMode:NotifyOnResize:Done", function onListeningResize() {
|
||||
mm.removeMessageListener("ResponsiveMode:NotifyOnResize:Done", onListeningResize);
|
||||
deferred.resolve();
|
||||
});
|
||||
return deferred.promise;
|
||||
},
|
||||
|
||||
onContentResize: function() {
|
||||
ResponsiveUIManager.emit("contentResize", { tab: this.tab });
|
||||
},
|
||||
|
||||
/**
|
||||
@ -427,12 +428,6 @@ ResponsiveUI.prototype = {
|
||||
this.screenshotbutton.className = "devtools-responsiveui-toolbarbutton devtools-responsiveui-screenshot";
|
||||
this.screenshotbutton.addEventListener("command", this.bound_screenshot, true);
|
||||
|
||||
this.touchbutton = this.chromeDoc.createElement("toolbarbutton");
|
||||
this.touchbutton.setAttribute("tabindex", "0");
|
||||
this.touchbutton.setAttribute("tooltiptext", this.strings.GetStringFromName("responsiveUI.touch"));
|
||||
this.touchbutton.className = "devtools-responsiveui-toolbarbutton devtools-responsiveui-touch";
|
||||
this.touchbutton.addEventListener("command", this.bound_touch, true);
|
||||
|
||||
this.closebutton = this.chromeDoc.createElement("toolbarbutton");
|
||||
this.closebutton.setAttribute("tabindex", "0");
|
||||
this.closebutton.className = "devtools-responsiveui-toolbarbutton devtools-responsiveui-close";
|
||||
@ -442,7 +437,16 @@ ResponsiveUI.prototype = {
|
||||
this.toolbar.appendChild(this.closebutton);
|
||||
this.toolbar.appendChild(this.menulist);
|
||||
this.toolbar.appendChild(this.rotatebutton);
|
||||
this.toolbar.appendChild(this.touchbutton);
|
||||
|
||||
if (!this.e10s) {
|
||||
this.touchbutton = this.chromeDoc.createElement("toolbarbutton");
|
||||
this.touchbutton.setAttribute("tabindex", "0");
|
||||
this.touchbutton.setAttribute("tooltiptext", this.strings.GetStringFromName("responsiveUI.touch"));
|
||||
this.touchbutton.className = "devtools-responsiveui-toolbarbutton devtools-responsiveui-touch";
|
||||
this.touchbutton.addEventListener("command", this.bound_touch, true);
|
||||
this.toolbar.appendChild(this.touchbutton);
|
||||
}
|
||||
|
||||
this.toolbar.appendChild(this.screenshotbutton);
|
||||
|
||||
// Resizers
|
||||
@ -583,8 +587,9 @@ ResponsiveUI.prototype = {
|
||||
this.selectedItem = menuitem;
|
||||
}
|
||||
|
||||
if (preset.custom)
|
||||
if (preset.custom) {
|
||||
this.customMenuitem = menuitem;
|
||||
}
|
||||
|
||||
this.setMenuLabel(menuitem, preset);
|
||||
fragment.appendChild(menuitem);
|
||||
@ -662,9 +667,7 @@ ResponsiveUI.prototype = {
|
||||
|
||||
if (!promptOk) {
|
||||
// Prompt has been cancelled
|
||||
let menuitem = this.customMenuitem;
|
||||
this.menulist.selectedItem = menuitem;
|
||||
this.currentPresetKey = this.customPreset.key;
|
||||
this.menulist.selectedItem = this.selectedItem;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -762,21 +765,7 @@ ResponsiveUI.prototype = {
|
||||
* @param aFileName name of the screenshot file (used for tests).
|
||||
*/
|
||||
screenshot: function RUI_screenshot(aFileName) {
|
||||
let window = this.browser.contentWindow;
|
||||
let document = window.document;
|
||||
let canvas = this.chromeDoc.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
|
||||
|
||||
let width = window.innerWidth;
|
||||
let height = window.innerHeight;
|
||||
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
|
||||
let ctx = canvas.getContext("2d");
|
||||
ctx.drawWindow(window, window.scrollX, window.scrollY, width, height, "#fff");
|
||||
|
||||
let filename = aFileName;
|
||||
|
||||
if (!filename) {
|
||||
let date = new Date();
|
||||
let month = ("0" + (date.getMonth() + 1)).substr(-2, 2);
|
||||
@ -785,12 +774,15 @@ ResponsiveUI.prototype = {
|
||||
let timeString = date.toTimeString().replace(/:/g, ".").split(" ")[0];
|
||||
filename = this.strings.formatStringFromName("responsiveUI.screenshotGeneratedFilename", [dateString, timeString], 2);
|
||||
}
|
||||
|
||||
canvas.toBlob(blob => {
|
||||
let chromeWindow = this.chromeDoc.defaultView;
|
||||
let url = chromeWindow.URL.createObjectURL(blob);
|
||||
chromeWindow.saveURL(url, filename + ".png", null, true, true, document.documentURIObject, document);
|
||||
});
|
||||
let mm = this.tab.linkedBrowser.messageManager;
|
||||
let chromeWindow = this.chromeDoc.defaultView;
|
||||
let doc = chromeWindow.document;
|
||||
function onScreenshot(aMessage) {
|
||||
mm.removeMessageListener("ResponsiveMode:RequestScreenshot:Done", onScreenshot);
|
||||
chromeWindow.saveURL(aMessage.data, filename + ".png", null, true, true, doc.documentURIObject, doc);
|
||||
}
|
||||
mm.addMessageListener("ResponsiveMode:RequestScreenshot:Done", onScreenshot);
|
||||
mm.sendAsyncMessage("ResponsiveMode:RequestScreenshot");
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,4 @@
|
||||
[DEFAULT]
|
||||
skip-if = e10s # Bug ?????? - devtools tests disabled with e10s
|
||||
subsuite = devtools
|
||||
support-files =
|
||||
head.js
|
||||
@ -7,8 +6,11 @@ support-files =
|
||||
|
||||
[browser_responsive_cmd.js]
|
||||
[browser_responsivecomputedview.js]
|
||||
skip-if = e10s # Bug ??????
|
||||
[browser_responsiveruleview.js]
|
||||
skip-if = e10s # Bug ??????
|
||||
[browser_responsiveui.js]
|
||||
[browser_responsiveui_touch.js]
|
||||
skip-if = e10s # Bug ?????? - [e10s] re-introduce touch feature in responsive mode
|
||||
[browser_responsiveuiaddcustompreset.js]
|
||||
[browser_responsive_devicewidth.js]
|
||||
|
@ -10,10 +10,11 @@ thisTestLeaksUncaughtRejectionsAndShouldBeFixed("destroy");
|
||||
|
||||
function test() {
|
||||
function isOpen() {
|
||||
return !!gBrowser.selectedTab.__responsiveUI;
|
||||
return gBrowser.getBrowserContainer(gBrowser.selectedTab.linkedBrowser)
|
||||
.hasAttribute("responsivemode");
|
||||
}
|
||||
|
||||
helpers.addTabWithToolbar("about:blank", function(options) {
|
||||
helpers.addTabWithToolbar("data:text/html;charset=utf-8,hi", function(options) {
|
||||
return helpers.audit(options, [
|
||||
{
|
||||
setup: "resize toggle",
|
||||
|
@ -7,21 +7,19 @@ function test() {
|
||||
|
||||
waitForExplicitFinish();
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedTab = gBrowser.addTab("about:logo");
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onload() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
|
||||
waitForFocus(startTest, content);
|
||||
startTest();
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,mop";
|
||||
|
||||
function startTest() {
|
||||
mgr.once("on", function() {executeSoon(onUIOpen)});
|
||||
document.getElementById("Tools:ResponsiveUI").doCommand();
|
||||
}
|
||||
|
||||
function onUIOpen() {
|
||||
instance = gBrowser.selectedTab.__responsiveUI;
|
||||
instance = mgr.getResponsiveUIForTab(gBrowser.selectedTab);
|
||||
instance.stack.setAttribute("notransition", "true");
|
||||
ok(instance, "instance of the module is attached to the tab.");
|
||||
|
||||
|
@ -8,11 +8,12 @@ function test() {
|
||||
let inspector;
|
||||
|
||||
waitForExplicitFinish();
|
||||
let mgr = ResponsiveUI.ResponsiveUIManager;
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onload() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
|
||||
waitForFocus(startTest, content);
|
||||
startTest();
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html;charset=utf-8,<html><style>" +
|
||||
@ -43,7 +44,7 @@ function test() {
|
||||
}
|
||||
|
||||
function onUIOpen() {
|
||||
instance = gBrowser.selectedTab.__responsiveUI;
|
||||
instance = mgr.getResponsiveUIForTab(gBrowser.selectedTab);
|
||||
ok(instance, "instance of the module is attached to the tab.");
|
||||
|
||||
instance.stack.setAttribute("notransition", "true");
|
||||
|
@ -11,10 +11,7 @@ function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onload() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
|
||||
waitForFocus(startTest, content);
|
||||
}, true);
|
||||
gBrowser.selectedBrowser.addEventListener("load", startTest, true);
|
||||
|
||||
content.location = "data:text/html;charset=utf-8,<html><style>" +
|
||||
"div {" +
|
||||
@ -34,12 +31,13 @@ function test() {
|
||||
}
|
||||
|
||||
function startTest() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", startTest, true);
|
||||
document.getElementById("Tools:ResponsiveUI").doCommand();
|
||||
executeSoon(onUIOpen);
|
||||
}
|
||||
|
||||
function onUIOpen() {
|
||||
instance = gBrowser.selectedTab.__responsiveUI;
|
||||
instance = mgr.getResponsiveUIForTab(gBrowser.selectedTab);
|
||||
ok(instance, "instance of the module is attached to the tab.");
|
||||
|
||||
instance.stack.setAttribute("notransition", "true");
|
||||
|
@ -1,27 +1,36 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
thisTestLeaksUncaughtRejectionsAndShouldBeFixed("Protocol error (unknownError): Error: Got an invalid root window in DocumentWalker");
|
||||
|
||||
function test() {
|
||||
let instance, widthBeforeClose, heightBeforeClose;
|
||||
let mgr = ResponsiveUI.ResponsiveUIManager;
|
||||
|
||||
waitForExplicitFinish();
|
||||
SimpleTest.requestCompleteLog();
|
||||
Task.spawn(function() {
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onload() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
|
||||
waitForFocus(startTest, content);
|
||||
}, true);
|
||||
function extractSizeFromString(str) {
|
||||
let numbers = str.match(/(\d+)[^\d]*(\d+)/);
|
||||
if (numbers) {
|
||||
return [numbers[1], numbers[2]];
|
||||
} else {
|
||||
return [null, null];
|
||||
}
|
||||
}
|
||||
|
||||
content.location = "data:text/html,mop";
|
||||
function processStringAsKey(str) {
|
||||
for (let i = 0, l = str.length; i < l; i++) {
|
||||
EventUtils.synthesizeKey(str.charAt(i), {});
|
||||
}
|
||||
}
|
||||
|
||||
yield addTab("data:text/html,mop");
|
||||
|
||||
let mgr = ResponsiveUI.ResponsiveUIManager;
|
||||
|
||||
function startTest() {
|
||||
document.getElementById("Tools:ResponsiveUI").removeAttribute("disabled");
|
||||
mgr.once("on", function() {executeSoon(onUIOpen)});
|
||||
synthesizeKeyFromKeyTag("key_responsiveUI");
|
||||
}
|
||||
|
||||
function onUIOpen() {
|
||||
yield once(mgr, "on");
|
||||
|
||||
// Is it open?
|
||||
let container = gBrowser.getBrowserContainer();
|
||||
is(container.getAttribute("responsivemode"), "true", "In responsive mode.");
|
||||
@ -29,75 +38,58 @@ function test() {
|
||||
// Menus are correctly updated?
|
||||
is(document.getElementById("Tools:ResponsiveUI").getAttribute("checked"), "true", "menus checked");
|
||||
|
||||
instance = gBrowser.selectedTab.__responsiveUI;
|
||||
let instance = mgr.getResponsiveUIForTab(gBrowser.selectedTab);
|
||||
ok(instance, "instance of the module is attached to the tab.");
|
||||
|
||||
if (instance._floatingScrollbars) {
|
||||
ensureScrollbarsAreFloating();
|
||||
}
|
||||
let originalWidth = content.innerWidth;
|
||||
content.location = "data:text/html;charset=utf-8,mop<div style%3D'height%3A5000px'><%2Fdiv>";
|
||||
let newWidth = content.innerWidth;
|
||||
is(originalWidth, newWidth, "Floating scrollbars are presents");
|
||||
|
||||
yield instance._test_notifyOnResize();
|
||||
|
||||
yield nextTick();
|
||||
|
||||
instance.transitionsEnabled = false;
|
||||
|
||||
testPresets();
|
||||
}
|
||||
|
||||
function ensureScrollbarsAreFloating() {
|
||||
let body = gBrowser.contentDocument.body;
|
||||
let html = gBrowser.contentDocument.documentElement;
|
||||
|
||||
let originalWidth = body.getBoundingClientRect().width;
|
||||
|
||||
html.style.overflowY = "scroll"; // Force scrollbars
|
||||
// Flush. Should not be needed as getBoundingClientRect() should flush,
|
||||
// but just in case.
|
||||
gBrowser.contentWindow.getComputedStyle(html).overflowY;
|
||||
let newWidth = body.getBoundingClientRect().width;
|
||||
is(originalWidth, newWidth, "Floating scrollbars are presents");
|
||||
}
|
||||
|
||||
function testPresets() {
|
||||
function testOnePreset(c) {
|
||||
if (c == 0) {
|
||||
executeSoon(testCustom);
|
||||
return;
|
||||
}
|
||||
instance.menulist.selectedIndex = c;
|
||||
// Starting from length - 4 because last 3 items are not presets : separator, addbutton and removebutton
|
||||
for (let c = instance.menulist.firstChild.childNodes.length - 4; c >= 0; c--) {
|
||||
let item = instance.menulist.firstChild.childNodes[c];
|
||||
let [width, height] = extractSizeFromString(item.getAttribute("label"));
|
||||
let onContentResize = once(mgr, "contentResize");
|
||||
instance.menulist.selectedIndex = c;
|
||||
yield onContentResize;
|
||||
is(content.innerWidth, width, "preset " + c + ": dimension valid (width)");
|
||||
is(content.innerHeight, height, "preset " + c + ": dimension valid (height)");
|
||||
|
||||
testOnePreset(c - 1);
|
||||
}
|
||||
// Starting from length - 4 because last 3 items are not presets : separator, addbutton and removebutton
|
||||
testOnePreset(instance.menulist.firstChild.childNodes.length - 4);
|
||||
}
|
||||
|
||||
function extractSizeFromString(str) {
|
||||
let numbers = str.match(/(\d+)[^\d]*(\d+)/);
|
||||
if (numbers) {
|
||||
return [numbers[1], numbers[2]];
|
||||
} else {
|
||||
return [null, null];
|
||||
}
|
||||
}
|
||||
// test custom
|
||||
|
||||
instance.setSize(100, 100);
|
||||
|
||||
yield once(mgr, "contentResize");
|
||||
|
||||
function testCustom() {
|
||||
let initialWidth = content.innerWidth;
|
||||
let initialHeight = content.innerHeight;
|
||||
|
||||
is(initialWidth, 100, "Width reset to 100");
|
||||
is(initialHeight, 100, "Height reset to 100");
|
||||
|
||||
let x = 2, y = 2;
|
||||
EventUtils.synthesizeMouse(instance.resizer, x, y, {type: "mousedown"}, window);
|
||||
x += 20; y += 10;
|
||||
EventUtils.synthesizeMouse(instance.resizer, x, y, {type: "mousemove"}, window);
|
||||
EventUtils.synthesizeMouse(instance.resizer, x, y, {type: "mouseup"}, window);
|
||||
|
||||
yield once(mgr, "contentResize");
|
||||
|
||||
let expectedWidth = initialWidth + 20;
|
||||
let expectedHeight = initialHeight + 10;
|
||||
info("initial width: " + initialWidth);
|
||||
info("initial height: " + initialHeight);
|
||||
is(content.innerWidth, expectedWidth, "Size correcty updated (width).");
|
||||
is(content.innerHeight, expectedHeight, "Size correcty updated (height).");
|
||||
is(content.innerWidth, expectedWidth, "Size correctly updated (width).");
|
||||
is(content.innerHeight, expectedHeight, "Size correctly updated (height).");
|
||||
|
||||
is(instance.menulist.selectedIndex, -1, "Custom menuitem cannot be selected");
|
||||
let label = instance.menulist.firstChild.firstChild.getAttribute("label");
|
||||
let value = instance.menulist.value;
|
||||
@ -108,71 +100,80 @@ function test() {
|
||||
[width, height] = extractSizeFromString(value);
|
||||
is(width, expectedWidth, "Value updated (width).");
|
||||
is(height, expectedHeight, "Value updated (height).");
|
||||
testCustom2();
|
||||
}
|
||||
|
||||
function testCustom2() {
|
||||
let initialWidth = content.innerWidth;
|
||||
let initialHeight = content.innerHeight;
|
||||
// With "shift" key pressed
|
||||
|
||||
let x = 2, y = 2;
|
||||
instance.setSize(100, 100);
|
||||
|
||||
yield once(mgr, "contentResize");
|
||||
|
||||
initialWidth = content.innerWidth;
|
||||
initialHeight = content.innerHeight;
|
||||
|
||||
x = 2; y = 2;
|
||||
EventUtils.synthesizeMouse(instance.resizer, x, y, {type: "mousedown"}, window);
|
||||
x += 23; y += 13;
|
||||
EventUtils.synthesizeMouse(instance.resizer, x, y, {type: "mousemove", shiftKey: true}, window);
|
||||
EventUtils.synthesizeMouse(instance.resizer, x, y, {type: "mouseup"}, window);
|
||||
|
||||
let expectedWidth = initialWidth + 20;
|
||||
let expectedHeight = initialHeight + 10;
|
||||
is(content.innerWidth, expectedWidth, "with shift: Size correcty updated (width).");
|
||||
is(content.innerHeight, expectedHeight, "with shift: Size correcty updated (height).");
|
||||
yield once(mgr, "contentResize");
|
||||
|
||||
expectedWidth = initialWidth + 20;
|
||||
expectedHeight = initialHeight + 10;
|
||||
is(content.innerWidth, expectedWidth, "with shift: Size correctly updated (width).");
|
||||
is(content.innerHeight, expectedHeight, "with shift: Size correctly updated (height).");
|
||||
is(instance.menulist.selectedIndex, -1, "with shift: Custom menuitem cannot be selected");
|
||||
let label = instance.menulist.firstChild.firstChild.getAttribute("label");
|
||||
let value = instance.menulist.value;
|
||||
isnot(label, value, "Label from the menulist item is different than the value of the menulist")
|
||||
let [width, height] = extractSizeFromString(label);
|
||||
label = instance.menulist.firstChild.firstChild.getAttribute("label");
|
||||
value = instance.menulist.value;
|
||||
isnot(label, value, "Label from the menulist item is different than the value of the menulist");
|
||||
[width, height] = extractSizeFromString(label);
|
||||
is(width, expectedWidth, "Label updated (width).");
|
||||
is(height, expectedHeight, "Label updated (height).");
|
||||
[width, height] = extractSizeFromString(value);
|
||||
is(width, expectedWidth, "Value updated (width).");
|
||||
is(height, expectedHeight, "Value updated (height).");
|
||||
testCustom3();
|
||||
}
|
||||
|
||||
function testCustom3() {
|
||||
let initialWidth = content.innerWidth;
|
||||
let initialHeight = content.innerHeight;
|
||||
|
||||
let x = 2, y = 2;
|
||||
// With "ctrl" key pressed
|
||||
|
||||
instance.setSize(100, 100);
|
||||
|
||||
yield once(mgr, "contentResize");
|
||||
|
||||
initialWidth = content.innerWidth;
|
||||
initialHeight = content.innerHeight;
|
||||
|
||||
x = 2; y = 2;
|
||||
EventUtils.synthesizeMouse(instance.resizer, x, y, {type: "mousedown"}, window);
|
||||
x += 60; y += 30;
|
||||
EventUtils.synthesizeMouse(instance.resizer, x, y, {type: "mousemove", ctrlKey: true}, window);
|
||||
EventUtils.synthesizeMouse(instance.resizer, x, y, {type: "mouseup"}, window);
|
||||
|
||||
let expectedWidth = initialWidth + 10;
|
||||
let expectedHeight = initialHeight + 5;
|
||||
is(content.innerWidth, expectedWidth, "with ctrl: Size correcty updated (width).");
|
||||
is(content.innerHeight, expectedHeight, "with ctrl: Size correcty updated (height).");
|
||||
yield once(mgr, "contentResize");
|
||||
|
||||
expectedWidth = initialWidth + 10;
|
||||
expectedHeight = initialHeight + 5;
|
||||
is(content.innerWidth, expectedWidth, "with ctrl: Size correctly updated (width).");
|
||||
is(content.innerHeight, expectedHeight, "with ctrl: Size correctly updated (height).");
|
||||
is(instance.menulist.selectedIndex, -1, "with ctrl: Custom menuitem cannot be selected");
|
||||
let label = instance.menulist.firstChild.firstChild.getAttribute("label");
|
||||
let value = instance.menulist.value;
|
||||
isnot(label, value, "Label from the menulist item is different than the value of the menulist")
|
||||
let [width, height] = extractSizeFromString(label);
|
||||
label = instance.menulist.firstChild.firstChild.getAttribute("label");
|
||||
value = instance.menulist.value;
|
||||
isnot(label, value, "Label from the menulist item is different than the value of the menulist");
|
||||
[width, height] = extractSizeFromString(label);
|
||||
is(width, expectedWidth, "Label updated (width).");
|
||||
is(height, expectedHeight, "Label updated (height).");
|
||||
[width, height] = extractSizeFromString(value);
|
||||
is(width, expectedWidth, "Value updated (width).");
|
||||
is(height, expectedHeight, "Value updated (height).");
|
||||
|
||||
testCustomInput();
|
||||
}
|
||||
|
||||
function testCustomInput() {
|
||||
let initialWidth = content.innerWidth;
|
||||
let initialHeight = content.innerHeight;
|
||||
let expectedWidth = initialWidth - 20;
|
||||
let expectedHeight = initialHeight - 10;
|
||||
// Test custom input
|
||||
|
||||
initialWidth = content.innerWidth;
|
||||
initialHeight = content.innerHeight;
|
||||
expectedWidth = initialWidth - 20;
|
||||
expectedHeight = initialHeight - 10;
|
||||
let index = instance.menulist.selectedIndex;
|
||||
let label, value, width, height;
|
||||
|
||||
let userInput = expectedWidth + " x " + expectedHeight;
|
||||
|
||||
@ -187,6 +188,8 @@ function test() {
|
||||
// Only the `change` event must change the size
|
||||
EventUtils.synthesizeKey("VK_RETURN", {});
|
||||
|
||||
yield once(mgr, "contentResize");
|
||||
|
||||
is(content.innerWidth, expectedWidth, "Size correctly updated (width).");
|
||||
is(content.innerHeight, expectedHeight, "Size correctly updated (height).");
|
||||
is(instance.menulist.selectedIndex, -1, "Custom menuitem cannot be selected");
|
||||
@ -200,17 +203,17 @@ function test() {
|
||||
is(width, expectedWidth, "Value updated (width).");
|
||||
is(height, expectedHeight, "Value updated (height).");
|
||||
|
||||
testCustomInput2();
|
||||
}
|
||||
|
||||
function testCustomInput2() {
|
||||
let initialWidth = content.innerWidth;
|
||||
let initialHeight = content.innerHeight;
|
||||
let index = instance.menulist.selectedIndex;
|
||||
// Invalid input
|
||||
|
||||
|
||||
initialWidth = content.innerWidth;
|
||||
initialHeight = content.innerHeight;
|
||||
index = instance.menulist.selectedIndex;
|
||||
let expectedValue = initialWidth + "x" + initialHeight;
|
||||
let expectedLabel = instance.menulist.firstChild.firstChild.getAttribute("label");
|
||||
|
||||
let userInput = "I'm wrong";
|
||||
userInput = "I'm wrong";
|
||||
|
||||
instance.menulist.inputField.value = "";
|
||||
instance.menulist.focus();
|
||||
@ -221,93 +224,75 @@ function test() {
|
||||
is(content.innerHeight, initialHeight, "Size hasn't changed (height).");
|
||||
is(instance.menulist.selectedIndex, index, "Selected item hasn't changed.");
|
||||
is(instance.menulist.value, expectedValue, "Value has been reset")
|
||||
let label = instance.menulist.firstChild.firstChild.getAttribute("label");
|
||||
label = instance.menulist.firstChild.firstChild.getAttribute("label");
|
||||
is(label, expectedLabel, "Custom menuitem's label hasn't changed");
|
||||
|
||||
rotate();
|
||||
}
|
||||
|
||||
function rotate() {
|
||||
let initialWidth = content.innerWidth;
|
||||
let initialHeight = content.innerHeight;
|
||||
// Rotate
|
||||
|
||||
initialWidth = content.innerWidth;
|
||||
initialHeight = content.innerHeight;
|
||||
|
||||
info("rotate");
|
||||
instance.rotate();
|
||||
|
||||
yield once(mgr, "contentResize");
|
||||
|
||||
is(content.innerWidth, initialHeight, "The width is now the height.");
|
||||
is(content.innerHeight, initialWidth, "The height is now the width.");
|
||||
let [width, height] = extractSizeFromString(instance.menulist.firstChild.firstChild.getAttribute("label"));
|
||||
[width, height] = extractSizeFromString(instance.menulist.firstChild.firstChild.getAttribute("label"));
|
||||
is(width, initialHeight, "Label updated (width).");
|
||||
is(height, initialWidth, "Label updated (height).");
|
||||
|
||||
widthBeforeClose = content.innerWidth;
|
||||
heightBeforeClose = content.innerHeight;
|
||||
let widthBeforeClose = content.innerWidth;
|
||||
let heightBeforeClose = content.innerHeight;
|
||||
|
||||
info("XXX BUG 851296: instance.closing: " + !!instance.closing);
|
||||
// Restart
|
||||
|
||||
mgr.once("off", function() {
|
||||
info("XXX BUG 851296: 'off' received.");
|
||||
executeSoon(restart);
|
||||
});
|
||||
mgr.toggle(window, gBrowser.selectedTab);
|
||||
}
|
||||
|
||||
function restart() {
|
||||
info("XXX BUG 851296: restarting.");
|
||||
info("XXX BUG 851296: __responsiveUI: " + gBrowser.selectedTab.__responsiveUI);
|
||||
mgr.once("on", function() {
|
||||
info("XXX BUG 851296: 'on' received.");
|
||||
executeSoon(onUIOpen2);
|
||||
});
|
||||
//XXX BUG 851296: synthesizeKeyFromKeyTag("key_responsiveUI");
|
||||
yield once(mgr, "off");
|
||||
|
||||
mgr.toggle(window, gBrowser.selectedTab);
|
||||
info("XXX BUG 851296: restart() finished.");
|
||||
}
|
||||
|
||||
function onUIOpen2() {
|
||||
info("XXX BUG 851296: onUIOpen2.");
|
||||
let container = gBrowser.getBrowserContainer();
|
||||
yield once(mgr, "on");
|
||||
|
||||
container = gBrowser.getBrowserContainer();
|
||||
is(container.getAttribute("responsivemode"), "true", "In responsive mode.");
|
||||
|
||||
// Menus are correctly updated?
|
||||
|
||||
is(document.getElementById("Tools:ResponsiveUI").getAttribute("checked"), "true", "menus checked");
|
||||
|
||||
is(content.innerWidth, widthBeforeClose, "width restored.");
|
||||
is(content.innerHeight, heightBeforeClose, "height restored.");
|
||||
|
||||
mgr.once("off", function() {executeSoon(testScreenshot)});
|
||||
mgr.toggle(window, gBrowser.selectedTab);
|
||||
}
|
||||
// Screenshot
|
||||
|
||||
|
||||
function testScreenshot() {
|
||||
let isWinXP = navigator.userAgent.indexOf("Windows NT 5.1") != -1;
|
||||
if (isWinXP) {
|
||||
// We have issues testing this on Windows XP.
|
||||
// See https://bugzilla.mozilla.org/show_bug.cgi?id=848760#c17
|
||||
return finishUp();
|
||||
}
|
||||
if (!isWinXP) {
|
||||
info("screenshot");
|
||||
instance.screenshot("responsiveui");
|
||||
let FileUtils = (Cu.import("resource://gre/modules/FileUtils.jsm", {})).FileUtils;
|
||||
|
||||
info("screenshot");
|
||||
instance.screenshot("responsiveui");
|
||||
let FileUtils = (Cu.import("resource://gre/modules/FileUtils.jsm", {})).FileUtils;
|
||||
|
||||
// while(1) until we find the file.
|
||||
// no need for a timeout, the test will get killed anyway.
|
||||
info("checking if file exists in 200ms");
|
||||
function checkIfFileExist() {
|
||||
let file = FileUtils.getFile("DfltDwnld", [ "responsiveui.png" ]);
|
||||
if (file.exists()) {
|
||||
ok(true, "Screenshot file exists");
|
||||
file.remove(false);
|
||||
finishUp();
|
||||
} else {
|
||||
setTimeout(checkIfFileExist, 200);
|
||||
while(true) {
|
||||
// while(true) until we find the file.
|
||||
// no need for a timeout, the test will get killed anyway.
|
||||
let file = FileUtils.getFile("DfltDwnld", [ "responsiveui.png" ]);
|
||||
if (file.exists()) {
|
||||
ok(true, "Screenshot file exists");
|
||||
file.remove(false);
|
||||
break;
|
||||
}
|
||||
info("checking if file exists in 200ms");
|
||||
yield wait(200);
|
||||
}
|
||||
}
|
||||
checkIfFileExist();
|
||||
}
|
||||
|
||||
function finishUp() {
|
||||
mgr.toggle(window, gBrowser.selectedTab);
|
||||
|
||||
yield once(mgr, "off");
|
||||
|
||||
// Menus are correctly updated?
|
||||
is(document.getElementById("Tools:ResponsiveUI").getAttribute("checked"), "false", "menu unchecked");
|
||||
@ -315,39 +300,6 @@ function test() {
|
||||
delete instance;
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}
|
||||
|
||||
function synthesizeKeyFromKeyTag(aKeyId) {
|
||||
let key = document.getElementById(aKeyId);
|
||||
isnot(key, null, "Successfully retrieved the <key> node");
|
||||
|
||||
let modifiersAttr = key.getAttribute("modifiers");
|
||||
|
||||
let name = null;
|
||||
|
||||
if (key.getAttribute("keycode"))
|
||||
name = key.getAttribute("keycode");
|
||||
else if (key.getAttribute("key"))
|
||||
name = key.getAttribute("key");
|
||||
|
||||
isnot(name, null, "Successfully retrieved keycode/key");
|
||||
|
||||
let modifiers = {
|
||||
shiftKey: modifiersAttr.match("shift"),
|
||||
ctrlKey: modifiersAttr.match("ctrl"),
|
||||
altKey: modifiersAttr.match("alt"),
|
||||
metaKey: modifiersAttr.match("meta"),
|
||||
accelKey: modifiersAttr.match("accel")
|
||||
}
|
||||
|
||||
info("XXX BUG 851296: key name: " + name);
|
||||
info("XXX BUG 851296: key modifiers: " + JSON.stringify(modifiers));
|
||||
EventUtils.synthesizeKey(name, modifiers);
|
||||
}
|
||||
|
||||
function processStringAsKey(str) {
|
||||
for (let i = 0, l = str.length; i < l; i++) {
|
||||
EventUtils.synthesizeKey(str.charAt(i), {});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ function test() {
|
||||
}
|
||||
|
||||
function testWithTouch() {
|
||||
gBrowser.selectedTab.__responsiveUI.enableTouch();
|
||||
mgr.getResponsiveUIForTab(gBrowser.selectedTab).enableTouch();
|
||||
let div = content.document.querySelector("div");
|
||||
let x = 2, y = 2;
|
||||
EventUtils.synthesizeMouse(div, x, y, {type: "mousedown", isSynthesized: false}, content);
|
||||
@ -47,7 +47,7 @@ function test() {
|
||||
}
|
||||
|
||||
function testWithTouchAgain() {
|
||||
gBrowser.selectedTab.__responsiveUI.disableTouch();
|
||||
mgr.getResponsiveUIForTab(gBrowser.selectedTab).disableTouch();
|
||||
let div = content.document.querySelector("div");
|
||||
let x = 2, y = 2;
|
||||
EventUtils.synthesizeMouse(div, x, y, {type: "mousedown", isSynthesized: false}, content);
|
||||
|
@ -2,170 +2,10 @@
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
function test() {
|
||||
let instance, deletedPresetA, deletedPresetB, oldPrompt;
|
||||
let mgr = ResponsiveUI.ResponsiveUIManager;
|
||||
|
||||
waitForExplicitFinish();
|
||||
SimpleTest.requestCompleteLog();
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onload() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
|
||||
waitForFocus(startTest, content);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html;charset=utf8,test custom presets in responsive mode";
|
||||
|
||||
// This test uses executeSoon() when responsive mode is initialized and when
|
||||
// it is destroyed such that we get out of the init/destroy loops. If we try
|
||||
// to init/destroy immediately, without waiting for the next loop, we get
|
||||
// intermittent test failures.
|
||||
|
||||
function startTest() {
|
||||
// Mocking prompt
|
||||
oldPrompt = Services.prompt;
|
||||
Services.prompt = {
|
||||
value: "",
|
||||
returnBool: true,
|
||||
prompt: function(aParent, aDialogTitle, aText, aValue, aCheckMsg, aCheckState) {
|
||||
aValue.value = this.value;
|
||||
return this.returnBool;
|
||||
}
|
||||
};
|
||||
|
||||
registerCleanupFunction(() => Services.prompt = oldPrompt);
|
||||
|
||||
info("test started, waiting for responsive mode to activate");
|
||||
|
||||
document.getElementById("Tools:ResponsiveUI").removeAttribute("disabled");
|
||||
mgr.once("on", onUIOpen);
|
||||
synthesizeKeyFromKeyTag("key_responsiveUI");
|
||||
}
|
||||
|
||||
function onUIOpen() {
|
||||
// Is it open?
|
||||
let container = gBrowser.getBrowserContainer();
|
||||
is(container.getAttribute("responsivemode"), "true", "In responsive mode.");
|
||||
|
||||
instance = gBrowser.selectedTab.__responsiveUI;
|
||||
ok(instance, "instance of the module is attached to the tab.");
|
||||
|
||||
instance.transitionsEnabled = false;
|
||||
|
||||
testAddCustomPreset();
|
||||
}
|
||||
|
||||
function testAddCustomPreset() {
|
||||
// Tries to add a custom preset and cancel the prompt
|
||||
let idx = instance.menulist.selectedIndex;
|
||||
let presetCount = instance.presets.length;
|
||||
|
||||
Services.prompt.value = "";
|
||||
Services.prompt.returnBool = false;
|
||||
instance.addbutton.doCommand();
|
||||
|
||||
is(idx, instance.menulist.selectedIndex, "selected item didn't change after add preset and cancel");
|
||||
is(presetCount, instance.presets.length, "number of presets didn't change after add preset and cancel");
|
||||
|
||||
let customHeight = 123, customWidth = 456;
|
||||
instance.setSize(customWidth, customHeight);
|
||||
|
||||
// Adds the custom preset with "Testing preset"
|
||||
Services.prompt.value = "Testing preset";
|
||||
Services.prompt.returnBool = true;
|
||||
instance.addbutton.doCommand();
|
||||
|
||||
instance.menulist.selectedIndex = 1;
|
||||
|
||||
info("waiting for responsive mode to turn off");
|
||||
mgr.once("off", restart);
|
||||
|
||||
// Force document reflow to avoid intermittent failures.
|
||||
info("document height " + document.height);
|
||||
|
||||
// We're still in the loop of initializing the responsive mode.
|
||||
// Let's wait next loop to stop it.
|
||||
executeSoon(function() {
|
||||
instance.close();
|
||||
});
|
||||
}
|
||||
|
||||
function restart() {
|
||||
info("Restarting Responsive Mode");
|
||||
mgr.once("on", function() {
|
||||
let container = gBrowser.getBrowserContainer();
|
||||
is(container.getAttribute("responsivemode"), "true", "In responsive mode.");
|
||||
|
||||
instance = gBrowser.selectedTab.__responsiveUI;
|
||||
|
||||
testCustomPresetInList();
|
||||
});
|
||||
|
||||
// We're still in the loop of destroying the responsive mode.
|
||||
// Let's wait next loop to start it.
|
||||
executeSoon(function() {
|
||||
synthesizeKeyFromKeyTag("key_responsiveUI");
|
||||
});
|
||||
}
|
||||
|
||||
function testCustomPresetInList() {
|
||||
let customPresetIndex = getPresetIndex("456x123 (Testing preset)");
|
||||
ok(customPresetIndex >= 0, "is the previously added preset (idx = " + customPresetIndex + ") in the list of items");
|
||||
|
||||
instance.menulist.selectedIndex = customPresetIndex;
|
||||
|
||||
is(content.innerWidth, 456, "add preset, and selected in the list, dimension valid (width)");
|
||||
is(content.innerHeight, 123, "add preset, and selected in the list, dimension valid (height)");
|
||||
|
||||
testDeleteCustomPresets();
|
||||
}
|
||||
|
||||
function testDeleteCustomPresets() {
|
||||
instance.removebutton.doCommand();
|
||||
|
||||
instance.menulist.selectedIndex = 2;
|
||||
deletedPresetA = instance.menulist.selectedItem.getAttribute("label");
|
||||
instance.removebutton.doCommand();
|
||||
|
||||
instance.menulist.selectedIndex = 2;
|
||||
deletedPresetB = instance.menulist.selectedItem.getAttribute("label");
|
||||
instance.removebutton.doCommand();
|
||||
|
||||
info("waiting for responsive mode to turn off");
|
||||
mgr.once("off", restartAgain);
|
||||
|
||||
// We're still in the loop of initializing the responsive mode.
|
||||
// Let's wait next loop to stop it.
|
||||
executeSoon(() => instance.close());
|
||||
}
|
||||
|
||||
function restartAgain() {
|
||||
info("waiting for responsive mode to turn on");
|
||||
mgr.once("on", () => {
|
||||
instance = gBrowser.selectedTab.__responsiveUI;
|
||||
testCustomPresetsNotInListAnymore();
|
||||
});
|
||||
|
||||
// We're still in the loop of destroying the responsive mode.
|
||||
// Let's wait next loop to start it.
|
||||
executeSoon(() => synthesizeKeyFromKeyTag("key_responsiveUI"));
|
||||
}
|
||||
|
||||
function testCustomPresetsNotInListAnymore() {
|
||||
let customPresetIndex = getPresetIndex(deletedPresetA);
|
||||
is(customPresetIndex, -1, "deleted preset " + deletedPresetA + " is not in the list anymore");
|
||||
|
||||
customPresetIndex = getPresetIndex(deletedPresetB);
|
||||
is(customPresetIndex, -1, "deleted preset " + deletedPresetB + " is not in the list anymore");
|
||||
|
||||
executeSoon(finishUp);
|
||||
}
|
||||
|
||||
function finishUp() {
|
||||
delete instance;
|
||||
gBrowser.removeCurrentTab();
|
||||
|
||||
finish();
|
||||
}
|
||||
let instance, deletedPresetA, deletedPresetB, oldPrompt;
|
||||
|
||||
function getPresetIndex(presetLabel) {
|
||||
function testOnePreset(c) {
|
||||
@ -199,4 +39,121 @@ function test() {
|
||||
|
||||
key.doCommand();
|
||||
}
|
||||
|
||||
Task.spawn(function() {
|
||||
|
||||
yield addTab("data:text/html;charset=utf8,test custom presets in responsive mode");
|
||||
|
||||
let mgr = ResponsiveUI.ResponsiveUIManager;
|
||||
|
||||
synthesizeKeyFromKeyTag("key_responsiveUI");
|
||||
|
||||
yield once(mgr, "on");
|
||||
|
||||
oldPrompt = Services.prompt;
|
||||
Services.prompt = {
|
||||
value: "",
|
||||
returnBool: true,
|
||||
prompt: function(aParent, aDialogTitle, aText, aValue, aCheckMsg, aCheckState) {
|
||||
aValue.value = this.value;
|
||||
return this.returnBool;
|
||||
}
|
||||
};
|
||||
|
||||
registerCleanupFunction(() => Services.prompt = oldPrompt);
|
||||
|
||||
// Is it open?
|
||||
let container = gBrowser.getBrowserContainer();
|
||||
is(container.getAttribute("responsivemode"), "true", "In responsive mode.");
|
||||
|
||||
instance = mgr.getResponsiveUIForTab(gBrowser.selectedTab);
|
||||
ok(instance, "instance of the module is attached to the tab.");
|
||||
|
||||
instance.transitionsEnabled = false;
|
||||
|
||||
yield instance._test_notifyOnResize();
|
||||
|
||||
// Tries to add a custom preset and cancel the prompt
|
||||
let idx = instance.menulist.selectedIndex;
|
||||
let presetCount = instance.presets.length;
|
||||
|
||||
Services.prompt.value = "";
|
||||
Services.prompt.returnBool = false;
|
||||
instance.addbutton.doCommand();
|
||||
|
||||
is(idx, instance.menulist.selectedIndex, "selected item didn't change after add preset and cancel");
|
||||
is(presetCount, instance.presets.length, "number of presets didn't change after add preset and cancel");
|
||||
|
||||
// Adds the custom preset with "Testing preset"
|
||||
Services.prompt.value = "Testing preset";
|
||||
Services.prompt.returnBool = true;
|
||||
|
||||
let customHeight = 123, customWidth = 456;
|
||||
instance.startResizing({});
|
||||
instance.setSize(customWidth, customHeight);
|
||||
instance.stopResizing({});
|
||||
|
||||
instance.addbutton.doCommand();
|
||||
|
||||
// Force document reflow to avoid intermittent failures.
|
||||
info("document height " + document.height);
|
||||
|
||||
instance.close();
|
||||
|
||||
info("waiting for responsive mode to turn off");
|
||||
yield once(mgr, "off");
|
||||
|
||||
// We're still in the loop of initializing the responsive mode.
|
||||
// Let's wait next loop to stop it.
|
||||
yield nextTick();
|
||||
|
||||
synthesizeKeyFromKeyTag("key_responsiveUI");
|
||||
|
||||
yield once(mgr, "on");
|
||||
|
||||
is(container.getAttribute("responsivemode"), "true", "In responsive mode.");
|
||||
|
||||
instance = mgr.getResponsiveUIForTab(gBrowser.selectedTab);
|
||||
|
||||
let customPresetIndex = getPresetIndex("456x123 (Testing preset)");
|
||||
info(customPresetIndex);
|
||||
ok(customPresetIndex >= 0, "is the previously added preset (idx = " + customPresetIndex + ") in the list of items");
|
||||
|
||||
instance.menulist.selectedIndex = customPresetIndex;
|
||||
|
||||
is(content.innerWidth, 456, "add preset, and selected in the list, dimension valid (width)");
|
||||
is(content.innerHeight, 123, "add preset, and selected in the list, dimension valid (height)");
|
||||
|
||||
instance.removebutton.doCommand();
|
||||
|
||||
instance.menulist.selectedIndex = 2;
|
||||
deletedPresetA = instance.menulist.selectedItem.getAttribute("label");
|
||||
instance.removebutton.doCommand();
|
||||
|
||||
instance.menulist.selectedIndex = 2;
|
||||
deletedPresetB = instance.menulist.selectedItem.getAttribute("label");
|
||||
instance.removebutton.doCommand();
|
||||
|
||||
yield nextTick();
|
||||
instance.close();
|
||||
yield once(mgr, "off");
|
||||
|
||||
synthesizeKeyFromKeyTag("key_responsiveUI");
|
||||
|
||||
info("waiting for responsive mode to turn on");
|
||||
yield once(mgr, "on");
|
||||
|
||||
instance = mgr.getResponsiveUIForTab(gBrowser.selectedTab);
|
||||
|
||||
customPresetIndex = getPresetIndex(deletedPresetA);
|
||||
is(customPresetIndex, -1, "deleted preset " + deletedPresetA + " is not in the list anymore");
|
||||
|
||||
customPresetIndex = getPresetIndex(deletedPresetB);
|
||||
is(customPresetIndex, -1, "deleted preset " + deletedPresetB + " is not in the list anymore");
|
||||
|
||||
yield nextTick();
|
||||
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
});
|
||||
}
|
||||
|
@ -123,3 +123,92 @@ function openComputedView() {
|
||||
function openRuleView() {
|
||||
return openInspectorSideBar("ruleview");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a new test tab in the browser and load the given url.
|
||||
* @param {String} url The url to be loaded in the new tab
|
||||
* @return a promise that resolves to the tab object when the url is loaded
|
||||
*/
|
||||
let addTab = Task.async(function* (url) {
|
||||
info("Adding a new tab with URL: '" + url + "'");
|
||||
|
||||
window.focus();
|
||||
|
||||
let tab = gBrowser.selectedTab = gBrowser.addTab(url);
|
||||
let browser = tab.linkedBrowser;
|
||||
|
||||
yield once(browser, "load", true);
|
||||
info("URL '" + url + "' loading complete");
|
||||
|
||||
return tab;
|
||||
});
|
||||
|
||||
/**
|
||||
* Wait for eventName on target.
|
||||
* @param {Object} target An observable object that either supports on/off or
|
||||
* addEventListener/removeEventListener
|
||||
* @param {String} eventName
|
||||
* @param {Boolean} useCapture Optional, for addEventListener/removeEventListener
|
||||
* @return A promise that resolves when the event has been handled
|
||||
*/
|
||||
function once(target, eventName, useCapture=false) {
|
||||
info("Waiting for event: '" + eventName + "' on " + target + ".");
|
||||
|
||||
let deferred = promise.defer();
|
||||
|
||||
for (let [add, remove] of [
|
||||
["addEventListener", "removeEventListener"],
|
||||
["addListener", "removeListener"],
|
||||
["on", "off"]
|
||||
]) {
|
||||
if ((add in target) && (remove in target)) {
|
||||
target[add](eventName, function onEvent(...aArgs) {
|
||||
info("Got event: '" + eventName + "' on " + target + ".");
|
||||
target[remove](eventName, onEvent, useCapture);
|
||||
deferred.resolve.apply(deferred, aArgs);
|
||||
}, useCapture);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function wait(ms) {
|
||||
let def = promise.defer();
|
||||
setTimeout(def.resolve, ms);
|
||||
return def.promise;
|
||||
}
|
||||
|
||||
function synthesizeKeyFromKeyTag(aKeyId) {
|
||||
let key = document.getElementById(aKeyId);
|
||||
isnot(key, null, "Successfully retrieved the <key> node");
|
||||
|
||||
let modifiersAttr = key.getAttribute("modifiers");
|
||||
|
||||
let name = null;
|
||||
|
||||
if (key.getAttribute("keycode"))
|
||||
name = key.getAttribute("keycode");
|
||||
else if (key.getAttribute("key"))
|
||||
name = key.getAttribute("key");
|
||||
|
||||
isnot(name, null, "Successfully retrieved keycode/key");
|
||||
|
||||
let modifiers = {
|
||||
shiftKey: modifiersAttr.match("shift"),
|
||||
ctrlKey: modifiersAttr.match("ctrl"),
|
||||
altKey: modifiersAttr.match("alt"),
|
||||
metaKey: modifiersAttr.match("meta"),
|
||||
accelKey: modifiersAttr.match("accel")
|
||||
}
|
||||
|
||||
EventUtils.synthesizeKey(name, modifiers);
|
||||
}
|
||||
|
||||
function nextTick() {
|
||||
let def = promise.defer();
|
||||
executeSoon(() => def.resolve())
|
||||
return def.promise;
|
||||
}
|
||||
|
@ -1,126 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
|
||||
|
||||
this.EXPORTED_SYMBOLS = [ "switchToFloatingScrollbars", "switchToNativeScrollbars" ];
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
let URL = Services.io.newURI("chrome://browser/skin/devtools/floating-scrollbars.css", null, null);
|
||||
|
||||
let trackedTabs = new WeakMap();
|
||||
|
||||
/**
|
||||
* Switch to floating scrollbars, à la mobile.
|
||||
*
|
||||
* @param aTab the targeted tab.
|
||||
*
|
||||
*/
|
||||
this.switchToFloatingScrollbars = function switchToFloatingScrollbars(aTab) {
|
||||
let mgr = trackedTabs.get(aTab);
|
||||
if (!mgr) {
|
||||
mgr = new ScrollbarManager(aTab);
|
||||
}
|
||||
mgr.switchToFloating();
|
||||
}
|
||||
|
||||
/**
|
||||
* Switch to original native scrollbars.
|
||||
*
|
||||
* @param aTab the targeted tab.
|
||||
*
|
||||
*/
|
||||
this.switchToNativeScrollbars = function switchToNativeScrollbars(aTab) {
|
||||
let mgr = trackedTabs.get(aTab);
|
||||
if (mgr) {
|
||||
mgr.reset();
|
||||
}
|
||||
}
|
||||
|
||||
function ScrollbarManager(aTab) {
|
||||
trackedTabs.set(aTab, this);
|
||||
|
||||
this.attachedTab = aTab;
|
||||
this.attachedBrowser = aTab.linkedBrowser;
|
||||
|
||||
this.reset = this.reset.bind(this);
|
||||
this.switchToFloating = this.switchToFloating.bind(this);
|
||||
|
||||
this.attachedTab.addEventListener("TabClose", this.reset, true);
|
||||
this.attachedBrowser.addEventListener("DOMContentLoaded", this.switchToFloating, true);
|
||||
}
|
||||
|
||||
ScrollbarManager.prototype = {
|
||||
get win() {
|
||||
return this.attachedBrowser.contentWindow;
|
||||
},
|
||||
|
||||
/*
|
||||
* Change the look of the scrollbars.
|
||||
*/
|
||||
switchToFloating: function() {
|
||||
let windows = this.getInnerWindows(this.win);
|
||||
windows.forEach(this.injectStyleSheet);
|
||||
this.forceStyle();
|
||||
},
|
||||
|
||||
|
||||
/*
|
||||
* Reset the look of the scrollbars.
|
||||
*/
|
||||
reset: function() {
|
||||
let windows = this.getInnerWindows(this.win);
|
||||
windows.forEach(this.removeStyleSheet);
|
||||
this.forceStyle(this.attachedBrowser);
|
||||
this.attachedBrowser.removeEventListener("DOMContentLoaded", this.switchToFloating, true);
|
||||
this.attachedTab.removeEventListener("TabClose", this.reset, true);
|
||||
trackedTabs.delete(this.attachedTab);
|
||||
},
|
||||
|
||||
/*
|
||||
* Toggle the display property of the window to force the style to be applied.
|
||||
*/
|
||||
forceStyle: function() {
|
||||
let parentWindow = this.attachedBrowser.ownerDocument.defaultView;
|
||||
let display = parentWindow.getComputedStyle(this.attachedBrowser).display; // Save display value
|
||||
this.attachedBrowser.style.display = "none";
|
||||
parentWindow.getComputedStyle(this.attachedBrowser).display; // Flush
|
||||
this.attachedBrowser.style.display = display; // Restore
|
||||
},
|
||||
|
||||
/*
|
||||
* return all the window objects present in the hiearchy of a window.
|
||||
*/
|
||||
getInnerWindows: function(win) {
|
||||
let iframes = win.document.querySelectorAll("iframe");
|
||||
let innerWindows = [];
|
||||
for (let iframe of iframes) {
|
||||
innerWindows = innerWindows.concat(this.getInnerWindows(iframe.contentWindow));
|
||||
}
|
||||
return [win].concat(innerWindows);
|
||||
},
|
||||
|
||||
/*
|
||||
* Append the new scrollbar style.
|
||||
*/
|
||||
injectStyleSheet: function(win) {
|
||||
let winUtils = win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
|
||||
try {
|
||||
winUtils.loadSheet(URL, win.AGENT_SHEET);
|
||||
}catch(e) {}
|
||||
},
|
||||
|
||||
/*
|
||||
* Remove the injected stylesheet.
|
||||
*/
|
||||
removeStyleSheet: function(win) {
|
||||
let winUtils = win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
|
||||
try {
|
||||
winUtils.removeSheet(URL, win.AGENT_SHEET);
|
||||
}catch(e) {}
|
||||
},
|
||||
}
|
@ -12,7 +12,6 @@ EXTRA_JS_MODULES.devtools += [
|
||||
'Curl.jsm',
|
||||
'DeveloperToolbar.jsm',
|
||||
'DOMHelpers.jsm',
|
||||
'FloatingScrollbars.jsm',
|
||||
'Jsbeautify.jsm',
|
||||
'Parser.jsm',
|
||||
'SplitView.jsm',
|
||||
|
@ -41,7 +41,7 @@ let WebAudioEditorController = {
|
||||
/**
|
||||
* Listen for events emitted by the current tab target.
|
||||
*/
|
||||
initialize: function() {
|
||||
initialize: Task.async(function* () {
|
||||
telemetry.toolOpened("webaudioeditor");
|
||||
this._onTabNavigated = this._onTabNavigated.bind(this);
|
||||
this._onThemeChange = this._onThemeChange.bind(this);
|
||||
@ -60,7 +60,10 @@ let WebAudioEditorController = {
|
||||
// the graph's marker styling, since we can't do this
|
||||
// with CSS
|
||||
gDevTools.on("pref-changed", this._onThemeChange);
|
||||
},
|
||||
|
||||
// Store the AudioNode definitions from the WebAudioFront
|
||||
AUDIO_NODE_DEFINITION = yield gFront.getDefinition();
|
||||
}),
|
||||
|
||||
/**
|
||||
* Remove events emitted by the current tab target.
|
||||
|
@ -15,6 +15,7 @@ const { require } = devtools;
|
||||
|
||||
let { console } = Cu.import("resource://gre/modules/devtools/Console.jsm", {});
|
||||
let { EventTarget } = require("sdk/event/target");
|
||||
|
||||
const { Task } = Cu.import("resource://gre/modules/Task.jsm", {});
|
||||
const { Class } = require("sdk/core/heritage");
|
||||
const EventEmitter = require("devtools/toolkit/event-emitter");
|
||||
@ -25,6 +26,10 @@ const telemetry = new Telemetry();
|
||||
devtools.lazyImporter(this, "LineGraphWidget",
|
||||
"resource:///modules/devtools/Graphs.jsm");
|
||||
|
||||
// `AUDIO_NODE_DEFINITION` defined in the controller's initialization,
|
||||
// which describes all the properties of an AudioNode
|
||||
let AUDIO_NODE_DEFINITION;
|
||||
|
||||
// Override DOM promises with Promise.jsm helpers
|
||||
const { defer, all } = Cu.import("resource://gre/modules/Promise.jsm", {}).Promise;
|
||||
|
||||
|
@ -35,6 +35,12 @@ const AudioNodeModel = Class({
|
||||
*/
|
||||
setup: Task.async(function* () {
|
||||
yield this.getType();
|
||||
|
||||
// Query bypass status on start up
|
||||
this._bypassed = yield this.isBypassed();
|
||||
|
||||
// Store whether or not this node is bypassable in the first place
|
||||
this.bypassable = !AUDIO_NODE_DEFINITION[this.type].unbypassable;
|
||||
}),
|
||||
|
||||
/**
|
||||
@ -75,6 +81,26 @@ const AudioNodeModel = Class({
|
||||
coreEmit(this, "disconnect", this);
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the bypass status of the audio node.
|
||||
*
|
||||
* @return Promise->Boolean
|
||||
*/
|
||||
isBypassed: function () {
|
||||
return this.actor.isBypassed();
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the bypass value of an AudioNode.
|
||||
*
|
||||
* @param Boolean enable
|
||||
* @return Promise
|
||||
*/
|
||||
bypass: function (enable) {
|
||||
this._bypassed = enable;
|
||||
return this.actor.bypass(enable).then(() => coreEmit(this, "bypass", this, enable));
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns a promise that resolves to an array of objects containing
|
||||
* both a `param` name property and a `value` property.
|
||||
@ -106,7 +132,8 @@ const AudioNodeModel = Class({
|
||||
graph.addNode(this.id, {
|
||||
type: this.type,
|
||||
label: this.type.replace(/Node$/, ""),
|
||||
id: this.id
|
||||
id: this.id,
|
||||
bypassed: this._bypassed
|
||||
});
|
||||
},
|
||||
|
||||
@ -279,7 +306,7 @@ const AudioNodesCollection = Class({
|
||||
this.remove(node);
|
||||
} else {
|
||||
// Pipe the event to the collection
|
||||
coreEmit(this, eventName, [node].concat(args));
|
||||
coreEmit(this, eventName, node, ...args);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -52,6 +52,7 @@ support-files =
|
||||
|
||||
[browser_wa_inspector.js]
|
||||
[browser_wa_inspector-toggle.js]
|
||||
[browser_wa_inspector-bypass-01.js]
|
||||
|
||||
[browser_wa_properties-view.js]
|
||||
[browser_wa_properties-view-edit-01.js]
|
||||
|
@ -15,14 +15,22 @@ add_task(function*() {
|
||||
is((yield gainNode.isBypassed()), false, "Nodes start off unbypassed.");
|
||||
|
||||
info("Calling node#bypass(true)");
|
||||
yield gainNode.bypass(true);
|
||||
let isBypassed = yield gainNode.bypass(true);
|
||||
|
||||
is(isBypassed, true, "node.bypass(true) resolves to true");
|
||||
is((yield gainNode.isBypassed()), true, "Node is now bypassed.");
|
||||
|
||||
info("Calling node#bypass(false)");
|
||||
yield gainNode.bypass(false);
|
||||
isBypassed = yield gainNode.bypass(false);
|
||||
|
||||
is(isBypassed, false, "node.bypass(false) resolves to false");
|
||||
is((yield gainNode.isBypassed()), false, "Node back to being unbypassed.");
|
||||
|
||||
info("Calling node#bypass(true) on unbypassable node");
|
||||
isBypassed = yield destNode.bypass(true);
|
||||
|
||||
is(isBypassed, false, "node.bypass(true) resolves to false for unbypassable node");
|
||||
is((yield gainNode.isBypassed()), false, "Unbypassable node is unaffect");
|
||||
|
||||
yield removeTab(target.tab);
|
||||
});
|
||||
|
@ -20,11 +20,12 @@ add_task(function*() {
|
||||
waitForGraphRendered(panelWin, 3, 2)
|
||||
]);
|
||||
let nodeIds = actors.map(actor => actor.actorID);
|
||||
let $tabbox = $("#web-audio-editor-tabs");
|
||||
|
||||
// Oscillator node
|
||||
click(panelWin, findGraphNode(panelWin, nodeIds[1]));
|
||||
yield waitForInspectorRender(panelWin, EVENTS);
|
||||
click(panelWin, $("#automation-tab"));
|
||||
$tabbox.selectedIndex = 1;
|
||||
|
||||
ok(isVisible($("#automation-graph-container")), "graph container should be visible");
|
||||
ok(isVisible($("#automation-content")), "automation content should be visible");
|
||||
@ -34,17 +35,17 @@ add_task(function*() {
|
||||
// Gain node
|
||||
click(panelWin, findGraphNode(panelWin, nodeIds[2]));
|
||||
yield waitForInspectorRender(panelWin, EVENTS);
|
||||
click(panelWin, $("#automation-tab"));
|
||||
$tabbox.selectedIndex = 1;
|
||||
|
||||
ok(!isVisible($("#automation-graph-container")), "graph container should be visible");
|
||||
ok(isVisible($("#automation-content")), "automation content should not be visible");
|
||||
ok(!isVisible($("#automation-graph-container")), "graph container should not be visible");
|
||||
ok(isVisible($("#automation-content")), "automation content should be visible");
|
||||
ok(isVisible($("#automation-no-events")), "no-events panel should be visible");
|
||||
ok(!isVisible($("#automation-empty")), "empty panel should not be visible");
|
||||
|
||||
// destination node
|
||||
click(panelWin, findGraphNode(panelWin, nodeIds[0]));
|
||||
yield waitForInspectorRender(panelWin, EVENTS);
|
||||
click(panelWin, $("#automation-tab"));
|
||||
$tabbox.selectedIndex = 1;
|
||||
|
||||
ok(!isVisible($("#automation-graph-container")), "graph container should not be visible");
|
||||
ok(!isVisible($("#automation-content")), "automation content should not be visible");
|
||||
|
@ -0,0 +1,67 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests that nodes are correctly bypassed when bypassing.
|
||||
*/
|
||||
|
||||
add_task(function*() {
|
||||
let { target, panel } = yield initWebAudioEditor(SIMPLE_CONTEXT_URL);
|
||||
let { panelWin } = panel;
|
||||
let { gFront, $, $$, EVENTS, gAudioNodes } = panelWin;
|
||||
|
||||
reload(target);
|
||||
|
||||
let [actors] = yield Promise.all([
|
||||
get3(gFront, "create-node"),
|
||||
waitForGraphRendered(panelWin, 3, 2)
|
||||
]);
|
||||
let nodeIds = actors.map(actor => actor.actorID);
|
||||
|
||||
click(panelWin, findGraphNode(panelWin, nodeIds[1]));
|
||||
// Wait for the node to be set as well as the inspector to come fully into the view
|
||||
yield Promise.all([
|
||||
waitForInspectorRender(panelWin, EVENTS),
|
||||
once(panelWin, EVENTS.UI_INSPECTOR_TOGGLED)
|
||||
]);
|
||||
|
||||
let $bypass = $("toolbarbutton.bypass");
|
||||
|
||||
is((yield actors[1].isBypassed()), false, "AudioNodeActor is not bypassed by default.")
|
||||
is($bypass.checked, true, "Button is 'on' for normal nodes");
|
||||
is($bypass.disabled, false, "Bypass button is not disabled for normal nodes");
|
||||
|
||||
command($bypass);
|
||||
yield gAudioNodes.once("bypass");
|
||||
|
||||
is((yield actors[1].isBypassed()), true, "AudioNodeActor is bypassed.")
|
||||
is($bypass.checked, false, "Button is 'off' when clicked");
|
||||
is($bypass.disabled, false, "Bypass button is not disabled after click");
|
||||
ok(findGraphNode(panelWin, nodeIds[1]).classList.contains("bypassed"),
|
||||
"AudioNode has 'bypassed' class.");
|
||||
|
||||
command($bypass);
|
||||
yield gAudioNodes.once("bypass");
|
||||
|
||||
is((yield actors[1].isBypassed()), false, "AudioNodeActor is no longer bypassed.")
|
||||
is($bypass.checked, true, "Button is back on when clicked");
|
||||
is($bypass.disabled, false, "Bypass button is not disabled after click");
|
||||
ok(!findGraphNode(panelWin, nodeIds[1]).classList.contains("bypassed"),
|
||||
"AudioNode no longer has 'bypassed' class.");
|
||||
|
||||
click(panelWin, findGraphNode(panelWin, nodeIds[0]));
|
||||
|
||||
yield once(panelWin, EVENTS.UI_INSPECTOR_NODE_SET);
|
||||
|
||||
is((yield actors[0].isBypassed()), false, "Unbypassable AudioNodeActor is not bypassed.");
|
||||
is($bypass.checked, false, "Button is 'off' for unbypassable nodes");
|
||||
is($bypass.disabled, true, "Bypass button is disabled for unbypassable nodes");
|
||||
|
||||
command($bypass);
|
||||
is((yield actors[0].isBypassed()), false,
|
||||
"Clicking button on unbypassable node does not change bypass state on actor.");
|
||||
is($bypass.checked, false, "Button is still 'off' for unbypassable nodes");
|
||||
is($bypass.disabled, true, "Bypass button is still disabled for unbypassable nodes");
|
||||
|
||||
yield teardown(target);
|
||||
});
|
@ -34,8 +34,6 @@ add_task(function*() {
|
||||
"InspectorView empty message should still be visible.");
|
||||
ok(!isVisible($("#web-audio-editor-tabs")),
|
||||
"InspectorView tabs view should still be hidden.");
|
||||
is($("#web-audio-inspector-title").value, "AudioNode Inspector",
|
||||
"Inspector should still have default title.");
|
||||
|
||||
// Close inspector pane
|
||||
$("#inspector-pane-toggle").click();
|
||||
@ -59,8 +57,6 @@ add_task(function*() {
|
||||
"Empty message hides even when loading node while open.");
|
||||
ok(isVisible($("#web-audio-editor-tabs")),
|
||||
"Switches to tab view when loading node while open.");
|
||||
is($("#web-audio-inspector-title").value, "Oscillator",
|
||||
"Inspector title updates when loading node while open.");
|
||||
|
||||
yield teardown(target);
|
||||
});
|
||||
|
@ -27,8 +27,6 @@ add_task(function*() {
|
||||
"InspectorView empty message should show when no node's selected.");
|
||||
ok(!isVisible($("#web-audio-editor-tabs")),
|
||||
"InspectorView tabs view should be hidden when no node's selected.");
|
||||
is($("#web-audio-inspector-title").value, "AudioNode Inspector",
|
||||
"Inspector should have default title when empty.");
|
||||
|
||||
// Wait for the node to be set as well as the inspector to come fully into the view
|
||||
let nodeSet = Promise.all([
|
||||
@ -44,9 +42,6 @@ add_task(function*() {
|
||||
ok(isVisible($("#web-audio-editor-tabs")),
|
||||
"InspectorView tabs view visible when node selected.");
|
||||
|
||||
is($("#web-audio-inspector-title").value, "Oscillator",
|
||||
"Inspector should have the node title when a node is selected.");
|
||||
|
||||
is($("#web-audio-editor-tabs").selectedIndex, 0,
|
||||
"default tab selected should be the parameters tab.");
|
||||
|
||||
@ -54,8 +49,5 @@ add_task(function*() {
|
||||
click(panelWin, findGraphNode(panelWin, nodeIds[2]));
|
||||
yield nodeSet;
|
||||
|
||||
is($("#web-audio-inspector-title").value, "Gain",
|
||||
"Inspector title updates when a new node is selected.");
|
||||
|
||||
yield teardown(target);
|
||||
});
|
||||
|
@ -318,6 +318,12 @@ function mouseOver (win, element) {
|
||||
EventUtils.sendMouseEvent({ type: "mouseover" }, element, win);
|
||||
}
|
||||
|
||||
function command (button) {
|
||||
let ev = button.ownerDocument.createEvent("XULCommandEvent");
|
||||
ev.initCommandEvent("command", true, true, button.ownerDocument.defaultView, 0, false, false, false, false, null);
|
||||
button.dispatchEvent(ev);
|
||||
}
|
||||
|
||||
function isVisible (element) {
|
||||
return !element.getAttribute("hidden");
|
||||
}
|
||||
|
@ -36,13 +36,13 @@ let ContextView = {
|
||||
* Initialization function, called when the tool is started.
|
||||
*/
|
||||
initialize: function() {
|
||||
this._onGraphNodeClick = this._onGraphNodeClick.bind(this);
|
||||
this._onGraphClick = this._onGraphClick.bind(this);
|
||||
this._onThemeChange = this._onThemeChange.bind(this);
|
||||
this._onStartContext = this._onStartContext.bind(this);
|
||||
this._onEvent = this._onEvent.bind(this);
|
||||
|
||||
this.draw = debounce(this.draw.bind(this), GRAPH_DEBOUNCE_TIMER);
|
||||
$('#graph-target').addEventListener('click', this._onGraphNodeClick, false);
|
||||
$("#graph-target").addEventListener("click", this._onGraphClick, false);
|
||||
|
||||
window.on(EVENTS.THEME_CHANGE, this._onThemeChange);
|
||||
window.on(EVENTS.START_CONTEXT, this._onStartContext);
|
||||
@ -58,7 +58,8 @@ let ContextView = {
|
||||
if (this._zoomBinding) {
|
||||
this._zoomBinding.on("zoom", null);
|
||||
}
|
||||
$('#graph-target').removeEventListener('click', this._onGraphNodeClick, false);
|
||||
$("#graph-target").removeEventListener("click", this._onGraphClick, false);
|
||||
|
||||
window.off(EVENTS.THEME_CHANGE, this._onThemeChange);
|
||||
window.off(EVENTS.START_CONTEXT, this._onStartContext);
|
||||
gAudioNodes.off("*", this._onEvent);
|
||||
@ -126,6 +127,15 @@ let ContextView = {
|
||||
return $(".nodes > g[data-id='" + actorID + "']");
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the appropriate class on an SVG node when its bypass
|
||||
* status is toggled.
|
||||
*/
|
||||
_bypassNode: function (node, enabled) {
|
||||
let el = this._getNodeByID(node.id);
|
||||
el.classList[enabled ? "add" : "remove"]("bypassed");
|
||||
},
|
||||
|
||||
/**
|
||||
* This method renders the nodes currently available in `gAudioNodes` and is
|
||||
* throttled to be called at most every `GRAPH_DEBOUNCE_TIMER` milliseconds.
|
||||
@ -143,42 +153,33 @@ let ContextView = {
|
||||
let oldDrawNodes = renderer.drawNodes();
|
||||
renderer.drawNodes(function(graph, root) {
|
||||
let svgNodes = oldDrawNodes(graph, root);
|
||||
svgNodes.attr("class", (n) => {
|
||||
svgNodes.each(function (n) {
|
||||
let node = graph.node(n);
|
||||
return "audionode type-" + node.type;
|
||||
});
|
||||
svgNodes.attr("data-id", (n) => {
|
||||
let node = graph.node(n);
|
||||
return node.id;
|
||||
let classString = "audionode type-" + node.type + (node.bypassed ? " bypassed" : "");
|
||||
this.setAttribute("class", classString);
|
||||
this.setAttribute("data-id", node.id);
|
||||
this.setAttribute("data-type", node.type);
|
||||
});
|
||||
return svgNodes;
|
||||
});
|
||||
|
||||
// Post-render manipulation of edges
|
||||
// TODO do all of this more efficiently, rather than
|
||||
// using the direct D3 helper utilities to loop over each
|
||||
// edge several times
|
||||
let oldDrawEdgePaths = renderer.drawEdgePaths();
|
||||
let defaultClasses = "edgePath enter";
|
||||
|
||||
renderer.drawEdgePaths(function(graph, root) {
|
||||
let svgEdges = oldDrawEdgePaths(graph, root);
|
||||
svgEdges.attr("data-source", (n) => {
|
||||
let edge = graph.edge(n);
|
||||
return edge.source;
|
||||
});
|
||||
svgEdges.attr("data-target", (n) => {
|
||||
let edge = graph.edge(n);
|
||||
return edge.target;
|
||||
});
|
||||
svgEdges.attr("data-param", (n) => {
|
||||
let edge = graph.edge(n);
|
||||
return edge.param ? edge.param : null;
|
||||
});
|
||||
// We have to manually specify the default classes on the edges
|
||||
// as to not overwrite them
|
||||
let defaultClasses = "edgePath enter";
|
||||
svgEdges.attr("class", (n) => {
|
||||
let edge = graph.edge(n);
|
||||
return defaultClasses + (edge.param ? (" param-connection " + edge.param) : "");
|
||||
svgEdges.each(function (e) {
|
||||
let edge = graph.edge(e);
|
||||
|
||||
// We have to manually specify the default classes on the edges
|
||||
// as to not overwrite them
|
||||
let edgeClass = defaultClasses + (edge.param ? (" param-connection " + edge.param) : "");
|
||||
|
||||
this.setAttribute("data-source", edge.source);
|
||||
this.setAttribute("data-target", edge.target);
|
||||
this.setAttribute("data-param", edge.param ? edge.param : null);
|
||||
this.setAttribute("class", edgeClass);
|
||||
});
|
||||
|
||||
return svgEdges;
|
||||
@ -263,6 +264,11 @@ let ContextView = {
|
||||
* in GRAPH_REDRAW_EVENTS) qualify as a redraw event.
|
||||
*/
|
||||
_onEvent: function (eventName, ...args) {
|
||||
// If bypassing, just toggle the class on the SVG node
|
||||
// rather than rerendering everything
|
||||
if (eventName === "bypass") {
|
||||
this._bypassNode.apply(this, args);
|
||||
}
|
||||
if (~GRAPH_REDRAW_EVENTS.indexOf(eventName)) {
|
||||
this.draw();
|
||||
}
|
||||
@ -280,12 +286,12 @@ let ContextView = {
|
||||
},
|
||||
|
||||
/**
|
||||
* Fired when a node in the svg graph is clicked. Used to handle triggering the AudioNodePane.
|
||||
* Fired when a click occurs in the graph.
|
||||
*
|
||||
* @param Event e
|
||||
* Click event.
|
||||
*/
|
||||
_onGraphNodeClick: function (e) {
|
||||
_onGraphClick: function (e) {
|
||||
let node = findGraphNodeParent(e.target);
|
||||
// If node not found (clicking outside of an audio node in the graph),
|
||||
// then ignore this event
|
||||
|
@ -43,8 +43,12 @@ let InspectorView = {
|
||||
this._onNodeSelect = this._onNodeSelect.bind(this);
|
||||
this._onDestroyNode = this._onDestroyNode.bind(this);
|
||||
this._onResize = this._onResize.bind(this);
|
||||
this._onCommandClick = this._onCommandClick.bind(this);
|
||||
|
||||
this.splitter.addEventListener("mouseup", this._onResize);
|
||||
for (let $el of $$("#audio-node-toolbar toolbarbutton")) {
|
||||
$el.addEventListener("command", this._onCommandClick);
|
||||
}
|
||||
window.on(EVENTS.UI_SELECT_NODE, this._onNodeSelect);
|
||||
gAudioNodes.on("remove", this._onDestroyNode);
|
||||
},
|
||||
@ -55,6 +59,11 @@ let InspectorView = {
|
||||
destroy: function () {
|
||||
this.unbindToggle();
|
||||
this.splitter.removeEventListener("mouseup", this._onResize);
|
||||
|
||||
$("#audio-node-toolbar toolbarbutton").removeEventListener("command", this._onCommandClick);
|
||||
for (let $el of $$("#audio-node-toolbar toolbarbutton")) {
|
||||
$el.removeEventListener("command", this._onCommandClick);
|
||||
}
|
||||
window.off(EVENTS.UI_SELECT_NODE, this._onNodeSelect);
|
||||
gAudioNodes.off("remove", this._onDestroyNode);
|
||||
|
||||
@ -67,7 +76,7 @@ let InspectorView = {
|
||||
* Takes a AudioNodeView `node` and sets it as the current
|
||||
* node and scaffolds the inspector view based off of the new node.
|
||||
*/
|
||||
setCurrentAudioNode: function (node) {
|
||||
setCurrentAudioNode: Task.async(function* (node) {
|
||||
this._currentNode = node || null;
|
||||
|
||||
// If no node selected, set the inspector back to "no AudioNode selected"
|
||||
@ -81,10 +90,10 @@ let InspectorView = {
|
||||
else {
|
||||
$("#web-audio-editor-details-pane-empty").setAttribute("hidden", "true");
|
||||
$("#web-audio-editor-tabs").removeAttribute("hidden");
|
||||
this._setTitle();
|
||||
yield this._buildToolbar();
|
||||
window.emit(EVENTS.UI_INSPECTOR_NODE_SET, this._currentNode.id);
|
||||
}
|
||||
},
|
||||
}),
|
||||
|
||||
/**
|
||||
* Returns the current AudioNodeView.
|
||||
@ -104,14 +113,25 @@ let InspectorView = {
|
||||
this.hideImmediately();
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the title of the Inspector view
|
||||
*/
|
||||
_setTitle: function () {
|
||||
let node = this._currentNode;
|
||||
let title = node.type.replace(/Node$/, "");
|
||||
$("#web-audio-inspector-title").setAttribute("value", title);
|
||||
},
|
||||
_buildToolbar: Task.async(function* () {
|
||||
let node = this.getCurrentAudioNode();
|
||||
|
||||
let bypassable = node.bypassable;
|
||||
let bypassed = yield node.isBypassed();
|
||||
let button = $("#audio-node-toolbar .bypass");
|
||||
|
||||
if (!bypassable) {
|
||||
button.setAttribute("disabled", true);
|
||||
} else {
|
||||
button.removeAttribute("disabled");
|
||||
}
|
||||
|
||||
if (!bypassable || bypassed) {
|
||||
button.removeAttribute("checked");
|
||||
} else {
|
||||
button.setAttribute("checked", true);
|
||||
}
|
||||
}),
|
||||
|
||||
/**
|
||||
* Event handlers
|
||||
@ -140,5 +160,26 @@ let InspectorView = {
|
||||
if (this._currentNode && this._currentNode.id === node.id) {
|
||||
this.setCurrentAudioNode(null);
|
||||
}
|
||||
},
|
||||
|
||||
_onCommandClick: function (e) {
|
||||
let node = this.getCurrentAudioNode();
|
||||
let button = e.target;
|
||||
let command = button.getAttribute("data-command");
|
||||
let checked = button.getAttribute("checked");
|
||||
|
||||
if (button.getAttribute("disabled")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (command === "bypass") {
|
||||
if (checked) {
|
||||
button.removeAttribute("checked");
|
||||
node.bypass(true);
|
||||
} else {
|
||||
button.setAttribute("checked", true);
|
||||
node.bypass(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -3,10 +3,10 @@
|
||||
- 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/. -->
|
||||
<?xml-stylesheet href="chrome://browser/skin/" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://browser/content/devtools/widgets.css" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://browser/skin/devtools/common.css" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://browser/skin/devtools/widgets.css" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://browser/skin/devtools/webaudioeditor.css" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://browser/content/devtools/widgets.css" type="text/css"?>
|
||||
<!DOCTYPE window [
|
||||
<!ENTITY % debuggerDTD SYSTEM "chrome://browser/locale/devtools/webaudioeditor.dtd">
|
||||
%debuggerDTD;
|
||||
@ -79,9 +79,6 @@
|
||||
</hbox>
|
||||
<splitter id="inspector-splitter" class="devtools-side-splitter"/>
|
||||
<vbox id="web-audio-inspector" hidden="true">
|
||||
<hbox class="devtools-toolbar">
|
||||
<label id="web-audio-inspector-title" value="&webAudioEditorUI.inspectorTitle;"></label>
|
||||
</hbox>
|
||||
<deck id="web-audio-editor-details-pane" flex="1">
|
||||
<vbox id="web-audio-editor-details-pane-empty" flex="1">
|
||||
<label value="&webAudioEditorUI.inspectorEmpty;"></label>
|
||||
@ -89,6 +86,13 @@
|
||||
<tabbox id="web-audio-editor-tabs"
|
||||
class="devtools-sidebar-tabs"
|
||||
handleCtrlTab="false">
|
||||
<toolbar id="audio-node-toolbar" class="devtools-toolbar">
|
||||
<hbox class="devtools-toolbarbutton-group">
|
||||
<toolbarbutton class="bypass devtools-toolbarbutton"
|
||||
data-command="bypass"
|
||||
tabindex="0"/>
|
||||
</hbox>
|
||||
</toolbar>
|
||||
<tabs>
|
||||
<tab id="properties-tab"
|
||||
label="&webAudioEditorUI.tab.properties;"/>
|
||||
|
@ -33,3 +33,7 @@ collapseInspector=Collapse inspector
|
||||
# that expands the inspector in the web audio tool UI.
|
||||
expandInspector=Expand inspector
|
||||
|
||||
# LOCALIZATION NOTE (webAudioEditorTooltipBypass): This is the tooltip for the
|
||||
# button that bypasses an AudioNode
|
||||
webAudioEditorTooltipBypass=Bypass AudioNode
|
||||
|
||||
|
@ -20,10 +20,10 @@ Cu.import("resource://gre/modules/Services.jsm");
|
||||
*/
|
||||
|
||||
/**
|
||||
* If a hang hasn't been reported for more than 5 seconds, assume the
|
||||
* If a hang hasn't been reported for more than 10 seconds, assume the
|
||||
* content process has gotten unstuck (and hide the hang notification).
|
||||
*/
|
||||
const HANG_EXPIRATION_TIME = 5000;
|
||||
const HANG_EXPIRATION_TIME = 10000;
|
||||
|
||||
let ProcessHangMonitor = {
|
||||
/**
|
||||
|
@ -229,6 +229,7 @@ browser.jar:
|
||||
skin/classic/browser/devtools/newtab-inverted.png (../shared/devtools/images/newtab-inverted.png)
|
||||
skin/classic/browser/devtools/newtab-inverted@2x.png (../shared/devtools/images/newtab-inverted@2x.png)
|
||||
* skin/classic/browser/devtools/widgets.css (devtools/widgets.css)
|
||||
skin/classic/browser/devtools/power.svg (../shared/devtools/images/power.svg)
|
||||
skin/classic/browser/devtools/filetype-dir-close.svg (../shared/devtools/images/filetypes/dir-close.svg)
|
||||
skin/classic/browser/devtools/filetype-dir-open.svg (../shared/devtools/images/filetypes/dir-open.svg)
|
||||
skin/classic/browser/devtools/filetype-globe.svg (../shared/devtools/images/filetypes/globe.svg)
|
||||
|
@ -360,6 +360,7 @@ browser.jar:
|
||||
skin/classic/browser/devtools/newtab-inverted.png (../shared/devtools/images/newtab-inverted.png)
|
||||
skin/classic/browser/devtools/newtab-inverted@2x.png (../shared/devtools/images/newtab-inverted@2x.png)
|
||||
* skin/classic/browser/devtools/widgets.css (devtools/widgets.css)
|
||||
skin/classic/browser/devtools/power.svg (../shared/devtools/images/power.svg)
|
||||
skin/classic/browser/devtools/filetype-dir-close.svg (../shared/devtools/images/filetypes/dir-close.svg)
|
||||
skin/classic/browser/devtools/filetype-dir-open.svg (../shared/devtools/images/filetypes/dir-open.svg)
|
||||
skin/classic/browser/devtools/filetype-globe.svg (../shared/devtools/images/filetypes/globe.svg)
|
||||
|
@ -13,4 +13,15 @@
|
||||
<feFuncB type="table" tableValues=".6 0"/>
|
||||
</feComponentTransfer>
|
||||
</filter>
|
||||
|
||||
<!-- Web Audio Gradients -->
|
||||
<linearGradient id="bypass-light" x1="6%" y1="8%" x2="12%" y2="12%" spreadMethod="repeat">
|
||||
<stop offset="0%" stop-color="#f0f1f2"/> <!-- theme-toolbar-background -->
|
||||
<stop offset="50%" stop-color="#fff"/>
|
||||
</linearGradient>
|
||||
|
||||
<linearGradient id="bypass-dark" x1="6%" y1="8%" x2="12%" y2="12%" spreadMethod="repeat">
|
||||
<stop offset="0%" stop-color="#343c45"/> <!-- theme-toolbar-background -->
|
||||
<stop offset="50%" stop-color="transparent"/>
|
||||
</linearGradient>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 592 B After Width: | Height: | Size: 1.1 KiB |
14
browser/themes/shared/devtools/images/power.svg
Normal file
14
browser/themes/shared/devtools/images/power.svg
Normal file
@ -0,0 +1,14 @@
|
||||
<!--
|
||||
Logo from raphaeljs.com, MIT License
|
||||
|
||||
Copyright © 2008 Dmitry Baranovskiy
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
The software is provided “as is”, without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the software or the use or other dealings in the software.
|
||||
-->
|
||||
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg">
|
||||
<path stroke="#edf0f1" d="m10.89891,2.50043c-0.49827,-0.24134 -1.09841,-0.03411 -1.34129,0.46514c-0.24185,0.49928 -0.03311,1.09942 0.46517,1.34128c1.56306,0.76071 2.64193,2.36094 2.64092,4.21555c-0.00501,2.58626 -2.09749,4.6787 -4.68322,4.68321c-2.58623,-0.005 -4.67869,-2.09746 -4.68371,-4.68321c-0.001,-1.85561 1.07834,-3.45731 2.64294,-4.21654c0.49928,-0.24185 0.7065,-0.84201 0.46514,-1.34129c-0.24185,-0.49825 -0.84098,-0.70697 -1.34029,-0.46513c-2.23396,1.08135 -3.77446,3.37351 -3.77545,6.02296c0.00099,3.69518 2.99518,6.68989 6.69138,6.69088c3.6957,-0.00099 6.69037,-2.9957 6.69089,-6.69088c-0.00102,-2.64846 -1.53948,-4.9391 -3.77247,-6.02197zm-2.91842,4.9346c0.55398,0 1.00309,-0.44861 1.00309,-1.00357l0,-4.68373c0,-0.55446 -0.44911,-1.00309 -1.00309,-1.00309c-0.555,0 -1.00358,0.44911 -1.00358,1.00309l0,4.68321c0,0.55499 0.44858,1.00409 1.00358,1.00409z" stroke-width="0" fill="#edf0f1"/>
|
||||
</svg>
|
@ -81,13 +81,47 @@ g.edgePath.param-connection {
|
||||
|
||||
.nodes rect {
|
||||
stroke: var(--theme-tab-toolbar-background);
|
||||
}
|
||||
.theme-light rect {
|
||||
fill: var(--theme-tab-toolbar-background);
|
||||
}
|
||||
.theme-dark rect {
|
||||
fill: var(--theme-toolbar-background);
|
||||
}
|
||||
|
||||
/**
|
||||
* Bypassed Nodes
|
||||
*/
|
||||
|
||||
.theme-light .nodes g.bypassed rect {
|
||||
fill: url(chrome://browser/skin/devtools/filters.svg#bypass-light);
|
||||
}
|
||||
.theme-dark .nodes g.bypassed rect {
|
||||
fill: url(chrome://browser/skin/devtools/filters.svg#bypass-dark);
|
||||
}
|
||||
.nodes g.bypassed.selected rect {
|
||||
stroke: var(--theme-selection-background);
|
||||
}
|
||||
|
||||
/*
|
||||
.nodes g.bypassed text {
|
||||
opacity: 0.8;
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Selected Nodes
|
||||
*/
|
||||
.nodes g.selected rect {
|
||||
fill: var(--theme-selection-background);
|
||||
}
|
||||
|
||||
/* Don't style bypassed nodes text different because it'd be illegible in light-theme */
|
||||
.theme-light g.selected:not(.bypassed) text {
|
||||
fill: var(--theme-toolbar-background);
|
||||
}
|
||||
|
||||
|
||||
/* Text in nodes and edges */
|
||||
text {
|
||||
cursor: default; /* override the "text" cursor */
|
||||
@ -100,9 +134,6 @@ text {
|
||||
fill: var(--theme-body-color-alt);
|
||||
}
|
||||
|
||||
.theme-light g.selected text {
|
||||
fill: var(--theme-toolbar-background);
|
||||
}
|
||||
|
||||
.nodes text {
|
||||
cursor: pointer;
|
||||
@ -178,6 +209,32 @@ text {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inspector toolbar
|
||||
*/
|
||||
|
||||
#audio-node-toolbar .bypass {
|
||||
list-style-image: url(power.svg);
|
||||
}
|
||||
|
||||
#audio-node-toolbar toolbarbutton[disabled] {
|
||||
opacity: 0.5;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.theme-dark #audio-node-toolbar toolbarbutton[checked] {
|
||||
background-color: #1d4f73; /* Select Highlight Blue */
|
||||
}
|
||||
.theme-light #audio-node-toolbar toolbarbutton[checked] {
|
||||
background-color: #4c9ed9; /* Select Highlight Blue */
|
||||
}
|
||||
|
||||
/* don't invert checked buttons so we can have white icons on light theme */
|
||||
#audio-node-toolbar toolbarbutton[checked] > .toolbarbutton-icon {
|
||||
filter: none;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Responsive Styles
|
||||
* `.devtools-responsive-container` takes care of most of
|
||||
|
@ -266,6 +266,7 @@ browser.jar:
|
||||
skin/classic/browser/devtools/newtab-inverted.png (../shared/devtools/images/newtab-inverted.png)
|
||||
skin/classic/browser/devtools/newtab-inverted@2x.png (../shared/devtools/images/newtab-inverted@2x.png)
|
||||
* skin/classic/browser/devtools/widgets.css (devtools/widgets.css)
|
||||
skin/classic/browser/devtools/power.svg (../shared/devtools/images/power.svg)
|
||||
skin/classic/browser/devtools/filetype-dir-close.svg (../shared/devtools/images/filetypes/dir-close.svg)
|
||||
skin/classic/browser/devtools/filetype-dir-open.svg (../shared/devtools/images/filetypes/dir-open.svg)
|
||||
skin/classic/browser/devtools/filetype-globe.svg (../shared/devtools/images/filetypes/globe.svg)
|
||||
@ -729,6 +730,7 @@ browser.jar:
|
||||
skin/classic/aero/browser/devtools/newtab-inverted.png (../shared/devtools/images/newtab-inverted.png)
|
||||
skin/classic/aero/browser/devtools/newtab-inverted@2x.png (../shared/devtools/images/newtab-inverted@2x.png)
|
||||
* skin/classic/aero/browser/devtools/widgets.css (devtools/widgets.css)
|
||||
skin/classic/aero/browser/devtools/power.svg (../shared/devtools/images/power.svg)
|
||||
skin/classic/aero/browser/devtools/filetype-dir-close.svg (../shared/devtools/images/filetypes/dir-close.svg)
|
||||
skin/classic/aero/browser/devtools/filetype-dir-open.svg (../shared/devtools/images/filetypes/dir-open.svg)
|
||||
skin/classic/aero/browser/devtools/filetype-globe.svg (../shared/devtools/images/filetypes/globe.svg)
|
||||
|
@ -39,7 +39,7 @@ if test $android_version -lt MIN_ANDROID_VERSION ; then
|
||||
fi
|
||||
|
||||
case "$target" in
|
||||
arm-linux*-android*|*-linuxandroid*)
|
||||
arm-*linux*-android*|*-linuxandroid*)
|
||||
android_tool_prefix="arm-linux-androideabi"
|
||||
;;
|
||||
i?86-*android*)
|
||||
|
@ -10,9 +10,9 @@ int operator+(X, int);
|
||||
int operator++(X);
|
||||
|
||||
void badArithmeticsInArgs() {
|
||||
int a;
|
||||
int a = 1;
|
||||
typedef int myint;
|
||||
myint b;
|
||||
myint b = 2;
|
||||
X goodObj1(a);
|
||||
goodObj1.baz(b);
|
||||
X badObj1(a + b); // expected-error{{cannot pass an arithmetic expression of built-in types to 'X'}}
|
||||
|
@ -35,7 +35,7 @@ GENERATED_INCLUDES += [
|
||||
]
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
'/netwerk/base/src',
|
||||
'/netwerk/base',
|
||||
'/netwerk/protocol/res',
|
||||
'/xpcom/components'
|
||||
]
|
||||
|
30
configure.in
30
configure.in
@ -2211,17 +2211,15 @@ ia64*-hpux*)
|
||||
_DEFINES_CXXFLAGS='-FI $(DEPTH)/dist/include/mozilla-config.h -DMOZILLA_CLIENT'
|
||||
CFLAGS="$CFLAGS -W3 -Gy"
|
||||
CXXFLAGS="$CXXFLAGS -W3 -Gy"
|
||||
if test "$_CC_SUITE" -ge "11" -a "$CPU_ARCH" = "x86"; then
|
||||
if test "$CPU_ARCH" = "x86"; then
|
||||
dnl VS2012+ defaults to -arch:SSE2.
|
||||
CFLAGS="$CFLAGS -arch:IA32"
|
||||
CXXFLAGS="$CXXFLAGS -arch:IA32"
|
||||
fi
|
||||
if test "$_CC_SUITE" -ge "12"; then
|
||||
dnl VS2013+ requires -FS when parallel building by make -jN.
|
||||
dnl If nothing, compiler sometimes causes C1041 error.
|
||||
CFLAGS="$CFLAGS -FS"
|
||||
CXXFLAGS="$CXXFLAGS -FS"
|
||||
fi
|
||||
dnl VS2013+ requires -FS when parallel building by make -jN.
|
||||
dnl If nothing, compiler sometimes causes C1041 error.
|
||||
CFLAGS="$CFLAGS -FS"
|
||||
CXXFLAGS="$CXXFLAGS -FS"
|
||||
# khuey says we can safely ignore MSVC warning C4251
|
||||
# MSVC warning C4244 (implicit type conversion may lose data) warns
|
||||
# and requires workarounds for perfectly valid code. Also, GCC/clang
|
||||
@ -2283,10 +2281,8 @@ ia64*-hpux*)
|
||||
dnl both SSSE3 and SSE4.1.
|
||||
HAVE_TOOLCHAIN_SUPPORT_MSSSE3=1
|
||||
HAVE_TOOLCHAIN_SUPPORT_MSSE4_1=1
|
||||
if test "$_CC_SUITE" -ge "11"; then
|
||||
dnl allow AVX2 code from VS2012
|
||||
HAVE_X86_AVX2=1
|
||||
fi
|
||||
dnl allow AVX2 code from VS2012
|
||||
HAVE_X86_AVX2=1
|
||||
MOZ_MEMORY=1
|
||||
fi
|
||||
AC_DEFINE(HAVE_SNPRINTF)
|
||||
@ -3886,6 +3882,8 @@ LIBJPEG_TURBO_ASFLAGS=
|
||||
LIBJPEG_TURBO_X86_ASM=
|
||||
LIBJPEG_TURBO_X64_ASM=
|
||||
LIBJPEG_TURBO_ARM_ASM=
|
||||
LIBJPEG_TURBO_ARM64_ASM=
|
||||
LIBJPEG_TURBO_MIPS_ASM=
|
||||
MOZ_PERMISSIONS=1
|
||||
MOZ_PLACES=1
|
||||
MOZ_SOCIAL=1
|
||||
@ -6154,6 +6152,14 @@ if test -n "$MOZ_LIBJPEG_TURBO"; then
|
||||
LIBJPEG_TURBO_ASFLAGS="-march=armv7-a -mfpu=neon"
|
||||
LIBJPEG_TURBO_ARM_ASM=1
|
||||
;;
|
||||
*:aarch64*)
|
||||
LIBJPEG_TURBO_ASFLAGS="-march=armv8-a"
|
||||
LIBJPEG_TURBO_ARM64_ASM=1
|
||||
;;
|
||||
*:mips*)
|
||||
LIBJPEG_TURBO_ASFLAGS="-mdspr2"
|
||||
LIBJPEG_TURBO_MIPS_ASM=1
|
||||
;;
|
||||
*:x86|*:i?86)
|
||||
if $CC -E -dM -</dev/null | grep -q __ELF__; then
|
||||
LIBJPEG_TURBO_ASFLAGS="-f elf32 -rnasm -pnasm -DPIC -DELF"
|
||||
@ -8831,6 +8837,8 @@ AC_SUBST(LIBJPEG_TURBO_ASFLAGS)
|
||||
AC_SUBST(LIBJPEG_TURBO_X86_ASM)
|
||||
AC_SUBST(LIBJPEG_TURBO_X64_ASM)
|
||||
AC_SUBST(LIBJPEG_TURBO_ARM_ASM)
|
||||
AC_SUBST(LIBJPEG_TURBO_ARM64_ASM)
|
||||
AC_SUBST(LIBJPEG_TURBO_MIPS_ASM)
|
||||
|
||||
AC_SUBST(MOZ_PACKAGE_JSSHELL)
|
||||
AC_SUBST(MOZ_FOLD_LIBS)
|
||||
|
@ -411,7 +411,7 @@ LOCAL_INCLUDES += [
|
||||
'/layout/style',
|
||||
'/layout/svg',
|
||||
'/layout/xul',
|
||||
'/netwerk/base/src',
|
||||
'/netwerk/base',
|
||||
'/widget',
|
||||
'/xpcom/ds',
|
||||
]
|
||||
|
@ -509,6 +509,8 @@ Event::PreventDefaultInternal(bool aCalledByDefaultHandler)
|
||||
// must be true when web apps check it after they call preventDefault().
|
||||
if (!aCalledByDefaultHandler) {
|
||||
mEvent->mFlags.mDefaultPreventedByContent = true;
|
||||
} else {
|
||||
mEvent->mFlags.mDefaultPreventedByChrome = true;
|
||||
}
|
||||
|
||||
if (!IsTrusted()) {
|
||||
@ -569,6 +571,8 @@ Event::InitEvent(const nsAString& aEventTypeArg,
|
||||
mEvent->mFlags.mCancelable = aCancelableArg;
|
||||
|
||||
mEvent->mFlags.mDefaultPrevented = false;
|
||||
mEvent->mFlags.mDefaultPreventedByContent = false;
|
||||
mEvent->mFlags.mDefaultPreventedByChrome = false;
|
||||
|
||||
// Clearing the old targets, so that the event is targeted correctly when
|
||||
// re-dispatching it.
|
||||
|
@ -204,7 +204,7 @@ protected:
|
||||
uint32_t mLoadID;
|
||||
};
|
||||
|
||||
class nsAsyncEventRunner : public nsMediaEvent
|
||||
class HTMLMediaElement::nsAsyncEventRunner : public nsMediaEvent
|
||||
{
|
||||
private:
|
||||
nsString mName;
|
||||
|
@ -217,8 +217,6 @@ public:
|
||||
layers::ImageContainer* GetImageContainer();
|
||||
|
||||
// Dispatch events
|
||||
using nsGenericHTMLElement::DispatchEvent;
|
||||
virtual nsresult DispatchEvent(const nsAString& aName) MOZ_FINAL MOZ_OVERRIDE;
|
||||
virtual nsresult DispatchAsyncEvent(const nsAString& aName) MOZ_FINAL MOZ_OVERRIDE;
|
||||
|
||||
// Dispatch events that were raised while in the bfcache
|
||||
@ -980,6 +978,11 @@ protected:
|
||||
// MediaElement doesn't yet have one then it will create it.
|
||||
TextTrackManager* GetOrCreateTextTrackManager();
|
||||
|
||||
class nsAsyncEventRunner;
|
||||
using nsGenericHTMLElement::DispatchEvent;
|
||||
// For nsAsyncEventRunner.
|
||||
nsresult DispatchEvent(const nsAString& aName);
|
||||
|
||||
// The current decoder. Load() has been called on this decoder.
|
||||
// At most one of mDecoder and mSrcStream can be non-null.
|
||||
nsRefPtr<MediaDecoder> mDecoder;
|
||||
|
@ -241,7 +241,7 @@ LOCAL_INCLUDES += [
|
||||
'/layout/style',
|
||||
'/layout/tables',
|
||||
'/layout/xul',
|
||||
'/netwerk/base/src',
|
||||
'/netwerk/base',
|
||||
]
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
100
dom/html/test/file_fullscreen-esc-context-menu.html
Normal file
100
dom/html/test/file_fullscreen-esc-context-menu.html
Normal file
@ -0,0 +1,100 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=910532
|
||||
|
||||
Verify that an ESC key press canceling the context menu
|
||||
won't exit DOM fullscreen.
|
||||
-->
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Text for bug 910532</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<script type="application/javascript" src="file_fullscreen-utils.js"></script>
|
||||
<style>
|
||||
body:-moz-full-screen {
|
||||
background-color: red;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<script type="application/javascript">
|
||||
|
||||
const Ci = SpecialPowers.Ci;
|
||||
|
||||
SimpleTest.requestFlakyTimeout("We need to wait a small time to confirm " +
|
||||
"that the first ESC key does not exit fullscreen.");
|
||||
|
||||
function ok(condition, msg) {
|
||||
opener.ok(condition, "[esc-context-menu] " + msg);
|
||||
}
|
||||
|
||||
function is(a, b, msg) {
|
||||
opener.is(a, b, "[esc-context-menu] " + msg);
|
||||
}
|
||||
|
||||
var contextMenu;
|
||||
var escapeSent = 0;
|
||||
|
||||
function sendEscape() {
|
||||
escapeSent++;
|
||||
synthesizeKey("VK_ESCAPE", {});
|
||||
}
|
||||
|
||||
function begin() {
|
||||
// Copy from browser/base/content/test/general/test_contextmenu.html
|
||||
var chromeWin = SpecialPowers.wrap(window)
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.QueryInterface(Ci.nsIDocShellTreeItem)
|
||||
.rootTreeItem
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindow)
|
||||
.QueryInterface(Ci.nsIDOMChromeWindow);
|
||||
contextMenu = chromeWin.document.getElementById("contentAreaContextMenu");
|
||||
ok(contextMenu, "Got context menu XUL");
|
||||
|
||||
addFullscreenChangeContinuation("enter", fullscreenEntered);
|
||||
SpecialPowers.setBoolPref("full-screen-api.approval-required", false);
|
||||
document.body.mozRequestFullScreen();
|
||||
}
|
||||
|
||||
function finish() {
|
||||
SpecialPowers.clearUserPref("full-screen-api.approval-required");
|
||||
opener.nextTest();
|
||||
}
|
||||
|
||||
function fullscreenEntered(event) {
|
||||
ok(document.mozFullScreen, "Should have entered fullscreen mode");
|
||||
is(document.mozFullScreenElement, document.body, "FSE should be doc");
|
||||
contextMenu.addEventListener("popupshown", contextMenuOpened, false);
|
||||
is(contextMenu.state, "closed", "Should not have opened context menu");
|
||||
synthesizeMouseAtCenter(document.body, {type: 'contextmenu', button: 2});
|
||||
}
|
||||
|
||||
function contextMenuOpened(event) {
|
||||
contextMenu.removeEventListener("popupshown", contextMenuOpened);
|
||||
is(contextMenu.state, "open", "Should have opened context menu");
|
||||
addFullscreenChangeContinuation("exit", fullscreenExited);
|
||||
contextMenu.addEventListener("popuphidden", contextMenuClosed, false);
|
||||
sendEscape();
|
||||
}
|
||||
|
||||
function contextMenuClosed(event) {
|
||||
is(contextMenu.state, "closed", "Should have closed context menu");
|
||||
setTimeout(function () {
|
||||
ok(document.mozFullScreen, "Should still be in fullscreen mode");
|
||||
sendEscape();
|
||||
}, 100);
|
||||
}
|
||||
|
||||
function fullscreenExited(event) {
|
||||
is(escapeSent, 2, "Only the second escape should exit fullscreen");
|
||||
ok(!document.mozFullScreen, "Should have left fullscreen mode");
|
||||
finish();
|
||||
}
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -51,6 +51,7 @@ support-files =
|
||||
file_fullscreen-api.html
|
||||
file_fullscreen-denied-inner.html
|
||||
file_fullscreen-denied.html
|
||||
file_fullscreen-esc-context-menu.html
|
||||
file_fullscreen-esc-exit-inner.html
|
||||
file_fullscreen-esc-exit.html
|
||||
file_fullscreen-hidden.html
|
||||
|
@ -39,6 +39,7 @@ var gTestWindows = [
|
||||
"file_fullscreen-ancestor-stacking-context.html",
|
||||
"file_fullscreen-multiple.html",
|
||||
"file_fullscreen-rollback.html",
|
||||
"file_fullscreen-esc-context-menu.html",
|
||||
"file_fullscreen-esc-exit.html",
|
||||
"file_fullscreen-denied.html",
|
||||
"file_fullscreen-api.html",
|
||||
|
@ -132,7 +132,7 @@ LOCAL_INCLUDES += [
|
||||
'/hal/sandbox',
|
||||
'/js/ipc',
|
||||
'/layout/base',
|
||||
'/netwerk/base/src',
|
||||
'/netwerk/base',
|
||||
'/toolkit/xre',
|
||||
'/uriloader/exthandler',
|
||||
'/widget',
|
||||
|
@ -16,7 +16,7 @@ FAIL_ON_WARNINGS = True
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
"/dom/base",
|
||||
"/netwerk/base/src",
|
||||
"/netwerk/base",
|
||||
]
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
@ -1253,7 +1253,7 @@ void MediaDecoder::DurationChanged()
|
||||
|
||||
if (mOwner && oldDuration != mDuration && !IsInfinite()) {
|
||||
DECODER_LOG("Duration changed to %lld", mDuration);
|
||||
mOwner->DispatchEvent(NS_LITERAL_STRING("durationchange"));
|
||||
mOwner->DispatchAsyncEvent(NS_LITERAL_STRING("durationchange"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,9 +21,6 @@ public:
|
||||
// Called by the media decoder to indicate that the download is progressing.
|
||||
virtual void DownloadProgressed() = 0;
|
||||
|
||||
// Dispatch a synchronous event to the decoder owner
|
||||
virtual nsresult DispatchEvent(const nsAString& aName) = 0;
|
||||
|
||||
// Dispatch an asynchronous event to the decoder owner
|
||||
virtual nsresult DispatchAsyncEvent(const nsAString& aName) = 0;
|
||||
|
||||
|
@ -333,8 +333,9 @@ RTCPeerConnection.prototype = {
|
||||
this._mustValidateRTCConfiguration(rtcConfig,
|
||||
"RTCPeerConnection constructor passed invalid RTCConfiguration");
|
||||
if (_globalPCList._networkdown || !this._win.navigator.onLine) {
|
||||
throw new this._win.DOMError("InvalidStateError",
|
||||
"Can't create RTCPeerConnections when the network is down");
|
||||
throw new this._win.DOMException(
|
||||
"Can't create RTCPeerConnections when the network is down",
|
||||
"InvalidStateError");
|
||||
}
|
||||
|
||||
this.makeGetterSetterEH("onaddstream");
|
||||
@ -351,7 +352,7 @@ RTCPeerConnection.prototype = {
|
||||
this.makeGetterSetterEH("onidpvalidationerror");
|
||||
|
||||
this._pc = new this._win.PeerConnectionImpl();
|
||||
this._taskChain = this._win.Promise.resolve();
|
||||
this._operationsChain = this._win.Promise.resolve();
|
||||
|
||||
this.__DOM_IMPL__._innerObject = this;
|
||||
this._observer = new this._win.PeerConnectionObserver(this.__DOM_IMPL__);
|
||||
@ -367,8 +368,9 @@ RTCPeerConnection.prototype = {
|
||||
|
||||
get _impl() {
|
||||
if (!this._pc) {
|
||||
throw new this._win.DOMError("InvalidStateError",
|
||||
"RTCPeerConnection is gone (did you enter Offline mode?)");
|
||||
throw new this._win.DOMException(
|
||||
"RTCPeerConnection is gone (did you enter Offline mode?)",
|
||||
"InvalidStateError");
|
||||
}
|
||||
return this._pc;
|
||||
},
|
||||
@ -383,19 +385,40 @@ RTCPeerConnection.prototype = {
|
||||
this.dispatchEvent.bind(this));
|
||||
},
|
||||
|
||||
/**
|
||||
* Add a function to the task chain.
|
||||
* onSuccess - legacy callback (optional)
|
||||
* onError - legacy callback (optional)
|
||||
*/
|
||||
_queue: function(func, onSuccess, onError) {
|
||||
let p = this._taskChain.then(() => {
|
||||
this._checkClosed(); // TODO: Move outside promise once Bug 1107592 is fixed.
|
||||
return func();
|
||||
// Add a function to the internal operations chain.
|
||||
|
||||
_chain: function(func) {
|
||||
this._checkClosed(); // out here DOMException line-numbers work.
|
||||
let p = this._operationsChain.then(() => {
|
||||
// Don't _checkClosed() inside the chain, because it throws, and spec
|
||||
// behavior as of this writing is to NOT reject outstanding promises on
|
||||
// close. This is what happens most of the time anyways, as the c++ code
|
||||
// stops calling us once closed, hanging the chain. However, c++ may
|
||||
// already have queued tasks on us, so if we're one of those then sit back.
|
||||
if (!this._closed) {
|
||||
return func();
|
||||
}
|
||||
});
|
||||
this._taskChain = p.catch(() => {}); // don't propagate errors in taskChain!
|
||||
return onSuccess? p.then(this._wrapLegacyCallback(onSuccess),
|
||||
this._wrapLegacyCallback(onError)) : p;
|
||||
// don't propagate errors in the operations chain (this is a fork of p).
|
||||
this._operationsChain = p.catch(() => {});
|
||||
return p;
|
||||
},
|
||||
|
||||
// This wrapper helps implement legacy callbacks in a manner that produces
|
||||
// correct line-numbers in errors, provided that methods validate their inputs
|
||||
// before putting themselves on the pc's operations chain.
|
||||
|
||||
_legacyCatch: function(onSuccess, onError, func) {
|
||||
if (!onSuccess) {
|
||||
return func();
|
||||
}
|
||||
try {
|
||||
return func().then(this._wrapLegacyCallback(onSuccess),
|
||||
this._wrapLegacyCallback(onError));
|
||||
} catch (e) {
|
||||
this._wrapLegacyCallback(onError)(e);
|
||||
return this._win.Promise.resolve(); // avoid webidl TypeError
|
||||
}
|
||||
},
|
||||
|
||||
_wrapLegacyCallback: function(func) {
|
||||
@ -417,46 +440,44 @@ RTCPeerConnection.prototype = {
|
||||
*
|
||||
* WebIDL normalizes structure for us, so we test well-formed stun/turn urls,
|
||||
* but not validity of servers themselves, before passing along to C++.
|
||||
* ErrorMsg is passed in to detail which array-entry failed, if any.
|
||||
*
|
||||
* msg - Error message to detail which array-entry failed, if any.
|
||||
*/
|
||||
_mustValidateRTCConfiguration: function(rtcConfig, errorMsg) {
|
||||
var errorCtor = this._win.DOMError;
|
||||
var warningFunc = this.logWarning.bind(this);
|
||||
function nicerNewURI(uriStr, errorMsg) {
|
||||
let ios = Cc['@mozilla.org/network/io-service;1'].getService(Ci.nsIIOService);
|
||||
_mustValidateRTCConfiguration: function(rtcConfig, msg) {
|
||||
let ios = Cc['@mozilla.org/network/io-service;1'].getService(Ci.nsIIOService);
|
||||
|
||||
let nicerNewURI = uriStr => {
|
||||
try {
|
||||
return ios.newURI(uriStr, null, null);
|
||||
} catch (e if (e.result == Cr.NS_ERROR_MALFORMED_URI)) {
|
||||
throw new errorCtor("", errorMsg + " - malformed URI: " + uriStr);
|
||||
throw new this._win.DOMException(msg + " - malformed URI: " + uriStr,
|
||||
"SyntaxError");
|
||||
}
|
||||
}
|
||||
function mustValidateServer(server) {
|
||||
};
|
||||
|
||||
rtcConfig.iceServers.forEach(server => {
|
||||
if (!server.url) {
|
||||
throw new errorCtor("", errorMsg + " - missing url");
|
||||
throw new this._win.DOMException(msg + " - missing url", "InvalidAccessError");
|
||||
}
|
||||
let url = nicerNewURI(server.url, errorMsg);
|
||||
let url = nicerNewURI(server.url);
|
||||
if (url.scheme in { turn:1, turns:1 }) {
|
||||
if (!server.username) {
|
||||
throw new errorCtor("", errorMsg + " - missing username: " + server.url);
|
||||
throw new this._win.DOMException(msg + " - missing username: " + server.url,
|
||||
"InvalidAccessError");
|
||||
}
|
||||
if (!server.credential) {
|
||||
throw new errorCtor("", errorMsg + " - missing credential: " +
|
||||
server.url);
|
||||
throw new this._win.DOMException(msg + " - missing credential: " + server.url,
|
||||
"InvalidAccessError");
|
||||
}
|
||||
}
|
||||
else if (!(url.scheme in { stun:1, stuns:1 })) {
|
||||
throw new errorCtor("", errorMsg + " - improper scheme: " + url.scheme);
|
||||
throw new this._win.DOMException(msg + " - improper scheme: " + url.scheme,
|
||||
"SyntaxError");
|
||||
}
|
||||
if (url.scheme in { stuns:1, turns:1 }) {
|
||||
warningFunc(url.scheme.toUpperCase() + " is not yet supported.", null, 0);
|
||||
this.logWarning(url.scheme.toUpperCase() + " is not yet supported.", null, 0);
|
||||
}
|
||||
}
|
||||
if (rtcConfig.iceServers) {
|
||||
let len = rtcConfig.iceServers.length;
|
||||
for (let i=0; i < len; i++) {
|
||||
mustValidateServer (rtcConfig.iceServers[i], errorMsg);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// Ideally, this should be of the form _checkState(state),
|
||||
@ -465,7 +486,8 @@ RTCPeerConnection.prototype = {
|
||||
// spec. See Bug 831756.
|
||||
_checkClosed: function() {
|
||||
if (this._closed) {
|
||||
throw new this._win.DOMError("InvalidStateError", "Peer connection is closed");
|
||||
throw new this._win.DOMException("Peer connection is closed",
|
||||
"InvalidStateError");
|
||||
}
|
||||
},
|
||||
|
||||
@ -529,227 +551,168 @@ RTCPeerConnection.prototype = {
|
||||
},
|
||||
|
||||
createOffer: function(optionsOrOnSuccess, onError, options) {
|
||||
|
||||
// TODO: Remove old constraint-like RTCOptions support soon (Bug 1064223).
|
||||
// Note that webidl bindings make o.mandatory implicit but not o.optional.
|
||||
function convertLegacyOptions(o) {
|
||||
// Detect (mandatory OR optional) AND no other top-level members.
|
||||
let lcy = ((o.mandatory && Object.keys(o.mandatory).length) || o.optional) &&
|
||||
Object.keys(o).length == (o.mandatory? 1 : 0) + (o.optional? 1 : 0);
|
||||
if (!lcy) {
|
||||
return false;
|
||||
}
|
||||
let old = o.mandatory || {};
|
||||
if (o.mandatory) {
|
||||
delete o.mandatory;
|
||||
}
|
||||
if (o.optional) {
|
||||
o.optional.forEach(one => {
|
||||
// The old spec had optional as an array of objects w/1 attribute each.
|
||||
// Assumes our JS-webidl bindings only populate passed-in properties.
|
||||
let key = Object.keys(one)[0];
|
||||
if (key && old[key] === undefined) {
|
||||
old[key] = one[key];
|
||||
}
|
||||
});
|
||||
delete o.optional;
|
||||
}
|
||||
o.offerToReceiveAudio = old.OfferToReceiveAudio;
|
||||
o.offerToReceiveVideo = old.OfferToReceiveVideo;
|
||||
o.mozDontOfferDataChannel = old.MozDontOfferDataChannel;
|
||||
o.mozBundleOnly = old.MozBundleOnly;
|
||||
Object.keys(o).forEach(k => {
|
||||
if (o[k] === undefined) {
|
||||
delete o[k];
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
let onSuccess;
|
||||
if (optionsOrOnSuccess && typeof optionsOrOnSuccess === "function") {
|
||||
if (typeof optionsOrOnSuccess == "function") {
|
||||
onSuccess = optionsOrOnSuccess;
|
||||
} else {
|
||||
options = optionsOrOnSuccess;
|
||||
onError = undefined;
|
||||
}
|
||||
if (options && convertLegacyOptions(options)) {
|
||||
this.logWarning(
|
||||
"Mandatory/optional in createOffer options is deprecated! Use " +
|
||||
JSON.stringify(options) + " instead (note the case difference)!",
|
||||
null, 0);
|
||||
}
|
||||
return this._queue(() => this._createOffer(options), onSuccess, onError);
|
||||
},
|
||||
return this._legacyCatch(onSuccess, onError, () => {
|
||||
|
||||
_createOffer: function(options) {
|
||||
return new this._win.Promise((resolve, reject) => {
|
||||
this._onCreateOfferSuccess = resolve;
|
||||
this._onCreateOfferFailure = reject;
|
||||
this._impl.createOffer(options);
|
||||
});
|
||||
},
|
||||
// TODO: Remove old constraint-like RTCOptions support soon (Bug 1064223).
|
||||
// Note that webidl bindings make o.mandatory implicit but not o.optional.
|
||||
function convertLegacyOptions(o) {
|
||||
// Detect (mandatory OR optional) AND no other top-level members.
|
||||
let lcy = ((o.mandatory && Object.keys(o.mandatory).length) || o.optional) &&
|
||||
Object.keys(o).length == (o.mandatory? 1 : 0) + (o.optional? 1 : 0);
|
||||
if (!lcy) {
|
||||
return false;
|
||||
}
|
||||
let old = o.mandatory || {};
|
||||
if (o.mandatory) {
|
||||
delete o.mandatory;
|
||||
}
|
||||
if (o.optional) {
|
||||
o.optional.forEach(one => {
|
||||
// The old spec had optional as an array of objects w/1 attribute each.
|
||||
// Assumes our JS-webidl bindings only populate passed-in properties.
|
||||
let key = Object.keys(one)[0];
|
||||
if (key && old[key] === undefined) {
|
||||
old[key] = one[key];
|
||||
}
|
||||
});
|
||||
delete o.optional;
|
||||
}
|
||||
o.offerToReceiveAudio = old.OfferToReceiveAudio;
|
||||
o.offerToReceiveVideo = old.OfferToReceiveVideo;
|
||||
o.mozDontOfferDataChannel = old.MozDontOfferDataChannel;
|
||||
o.mozBundleOnly = old.MozBundleOnly;
|
||||
Object.keys(o).forEach(k => {
|
||||
if (o[k] === undefined) {
|
||||
delete o[k];
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
_createAnswer: function() {
|
||||
return new this._win.Promise((resolve, reject) => {
|
||||
if (!this.remoteDescription) {
|
||||
throw new this._win.DOMError("InvalidStateError",
|
||||
"setRemoteDescription not called");
|
||||
if (options && convertLegacyOptions(options)) {
|
||||
this.logWarning(
|
||||
"Mandatory/optional in createOffer options is deprecated! Use " +
|
||||
JSON.stringify(options) + " instead (note the case difference)!",
|
||||
null, 0);
|
||||
}
|
||||
if (this.remoteDescription.type != "offer") {
|
||||
throw new this._win.DOMError("InvalidStateError",
|
||||
"No outstanding offer");
|
||||
}
|
||||
this._onCreateAnswerSuccess = resolve;
|
||||
this._onCreateAnswerFailure = reject;
|
||||
this._impl.createAnswer();
|
||||
return this._chain(() => new this._win.Promise((resolve, reject) => {
|
||||
this._onCreateOfferSuccess = resolve;
|
||||
this._onCreateOfferFailure = reject;
|
||||
this._impl.createOffer(options);
|
||||
}));
|
||||
});
|
||||
},
|
||||
|
||||
createAnswer: function(onSuccess, onError) {
|
||||
return this._queue(() => this._createAnswer(), onSuccess, onError);
|
||||
return this._legacyCatch(onSuccess, onError, () => {
|
||||
return this._chain(() => new this._win.Promise((resolve, reject) => {
|
||||
// We give up line-numbers in errors by doing this here, but do all
|
||||
// state-checks inside the chain, to support the legacy feature that
|
||||
// callers don't have to wait for setRemoteDescription to finish.
|
||||
if (!this.remoteDescription) {
|
||||
throw new this._win.DOMException("setRemoteDescription not called",
|
||||
"InvalidStateError");
|
||||
}
|
||||
if (this.remoteDescription.type != "offer") {
|
||||
throw new this._win.DOMException("No outstanding offer",
|
||||
"InvalidStateError");
|
||||
}
|
||||
this._onCreateAnswerSuccess = resolve;
|
||||
this._onCreateAnswerFailure = reject;
|
||||
this._impl.createAnswer();
|
||||
}));
|
||||
});
|
||||
},
|
||||
|
||||
setLocalDescription: function(desc, onSuccess, onError) {
|
||||
this._localType = desc.type;
|
||||
return this._legacyCatch(onSuccess, onError, () => {
|
||||
this._localType = desc.type;
|
||||
|
||||
let type;
|
||||
switch (desc.type) {
|
||||
case "offer":
|
||||
type = Ci.IPeerConnection.kActionOffer;
|
||||
break;
|
||||
case "answer":
|
||||
type = Ci.IPeerConnection.kActionAnswer;
|
||||
break;
|
||||
case "pranswer":
|
||||
throw new this._win.DOMError("NotSupportedError", "pranswer not yet implemented");
|
||||
default:
|
||||
throw new this._win.DOMError("InvalidParameterError",
|
||||
"Invalid type " + desc.type + " provided to setLocalDescription");
|
||||
}
|
||||
|
||||
return this._queue(() => this._setLocalDescription(type, desc.sdp),
|
||||
onSuccess, onError);
|
||||
},
|
||||
|
||||
_setLocalDescription: function(type, sdp) {
|
||||
return new this._win.Promise((resolve, reject) => {
|
||||
this._onSetLocalDescriptionSuccess = resolve;
|
||||
this._onSetLocalDescriptionFailure = reject;
|
||||
this._impl.setLocalDescription(type, sdp);
|
||||
let type;
|
||||
switch (desc.type) {
|
||||
case "offer":
|
||||
type = Ci.IPeerConnection.kActionOffer;
|
||||
break;
|
||||
case "answer":
|
||||
type = Ci.IPeerConnection.kActionAnswer;
|
||||
break;
|
||||
case "pranswer":
|
||||
throw new this._win.DOMException("pranswer not yet implemented",
|
||||
"NotSupportedError");
|
||||
default:
|
||||
throw new this._win.DOMException(
|
||||
"Invalid type " + desc.type + " provided to setLocalDescription",
|
||||
"InvalidParameterError");
|
||||
}
|
||||
return this._chain(() => new this._win.Promise((resolve, reject) => {
|
||||
this._onSetLocalDescriptionSuccess = resolve;
|
||||
this._onSetLocalDescriptionFailure = reject;
|
||||
this._impl.setLocalDescription(type, desc.sdp);
|
||||
}));
|
||||
});
|
||||
},
|
||||
|
||||
setRemoteDescription: function(desc, onSuccess, onError) {
|
||||
this._remoteType = desc.type;
|
||||
return this._legacyCatch(onSuccess, onError, () => {
|
||||
this._remoteType = desc.type;
|
||||
|
||||
let type;
|
||||
switch (desc.type) {
|
||||
case "offer":
|
||||
type = Ci.IPeerConnection.kActionOffer;
|
||||
break;
|
||||
case "answer":
|
||||
type = Ci.IPeerConnection.kActionAnswer;
|
||||
break;
|
||||
case "pranswer":
|
||||
throw new this._win.DOMError("NotSupportedError", "pranswer not yet implemented");
|
||||
default:
|
||||
throw new this._win.DOMError("InvalidParameterError",
|
||||
"Invalid type " + desc.type + " provided to setRemoteDescription");
|
||||
}
|
||||
|
||||
// Have to get caller's origin outside of Promise constructor and pass it in
|
||||
let origin = Cu.getWebIDLCallerPrincipal().origin;
|
||||
|
||||
return this._queue(() => this._setRemoteDescription(type, desc.sdp, origin),
|
||||
onSuccess, onError);
|
||||
},
|
||||
|
||||
/**
|
||||
* Takes a result from the IdP and checks it against expectations.
|
||||
* If OK, generates events.
|
||||
* Returns true if it is either present and valid, or if there is no
|
||||
* need for identity.
|
||||
*/
|
||||
_processIdpResult: function(message) {
|
||||
let good = !!message;
|
||||
// This might be a valid assertion, but if we are constrained to a single peer
|
||||
// identity, then we also need to make sure that the assertion matches
|
||||
if (good && this._impl.peerIdentity) {
|
||||
good = (message.identity === this._impl.peerIdentity);
|
||||
}
|
||||
if (good) {
|
||||
this._impl.peerIdentity = message.identity;
|
||||
this._peerIdentity = new this._win.RTCIdentityAssertion(
|
||||
this._remoteIdp.provider, message.identity);
|
||||
this.dispatchEvent(new this._win.Event("peeridentity"));
|
||||
}
|
||||
return good;
|
||||
},
|
||||
|
||||
_setRemoteDescription: function(type, sdp, origin) {
|
||||
return new this._win.Promise((resolve, reject) =>
|
||||
this._setRemoteDescriptionImpl(type, sdp, origin, resolve, reject));
|
||||
},
|
||||
|
||||
_setRemoteDescriptionImpl: function(type, sdp, origin, onSuccess, onError) {
|
||||
let idpComplete = false;
|
||||
let setRemoteComplete = false;
|
||||
let idpError = null;
|
||||
let isDone = false;
|
||||
|
||||
// we can run the IdP validation in parallel with setRemoteDescription this
|
||||
// complicates much more than would be ideal, but it ensures that the IdP
|
||||
// doesn't hold things up too much when it's not on the critical path
|
||||
let allDone = () => {
|
||||
if (!setRemoteComplete || !idpComplete || isDone) {
|
||||
return;
|
||||
let type;
|
||||
switch (desc.type) {
|
||||
case "offer":
|
||||
type = Ci.IPeerConnection.kActionOffer;
|
||||
break;
|
||||
case "answer":
|
||||
type = Ci.IPeerConnection.kActionAnswer;
|
||||
break;
|
||||
case "pranswer":
|
||||
throw new this._win.DOMException("pranswer not yet implemented",
|
||||
"NotSupportedError");
|
||||
default:
|
||||
throw new this._win.DOMException(
|
||||
"Invalid type " + desc.type + " provided to setRemoteDescription",
|
||||
"InvalidParameterError");
|
||||
}
|
||||
// May be null if the user didn't supply success/failure callbacks.
|
||||
// Violation of spec, but we allow it for now
|
||||
onSuccess();
|
||||
isDone = true;
|
||||
};
|
||||
|
||||
let setRemoteDone = () => {
|
||||
setRemoteComplete = true;
|
||||
allDone();
|
||||
};
|
||||
// Get caller's origin before chaining and pass it in
|
||||
let origin = Cu.getWebIDLCallerPrincipal().origin;
|
||||
|
||||
// If we aren't waiting for something specific, allow this
|
||||
// to complete asynchronously.
|
||||
let idpDone;
|
||||
if (!this._impl.peerIdentity) {
|
||||
idpDone = this._processIdpResult.bind(this);
|
||||
idpComplete = true; // lie about this for allDone()
|
||||
} else {
|
||||
idpDone = message => {
|
||||
let idpGood = this._processIdpResult(message);
|
||||
if (!idpGood) {
|
||||
// iff we are waiting for a very specific peerIdentity
|
||||
// call the error callback directly and then close
|
||||
idpError = "Peer Identity mismatch, expected: " +
|
||||
this._impl.peerIdentity;
|
||||
onError(idpError);
|
||||
this.close();
|
||||
} else {
|
||||
idpComplete = true;
|
||||
allDone();
|
||||
}
|
||||
};
|
||||
}
|
||||
return this._chain(() => {
|
||||
let expectedIdentity = this._impl.peerIdentity;
|
||||
|
||||
try {
|
||||
this._remoteIdp.verifyIdentityFromSDP(sdp, origin, idpDone);
|
||||
} catch (e) {
|
||||
// if processing the SDP for identity doesn't work
|
||||
this.logWarning(e.message, e.fileName, e.lineNumber);
|
||||
idpDone(null);
|
||||
}
|
||||
// Do setRemoteDescription and identity validation in parallel
|
||||
let p = new this._win.Promise((resolve, reject) => {
|
||||
this._onSetRemoteDescriptionSuccess = resolve;
|
||||
this._onSetRemoteDescriptionFailure = reject;
|
||||
this._impl.setRemoteDescription(type, desc.sdp);
|
||||
});
|
||||
|
||||
this._onSetRemoteDescriptionSuccess = setRemoteDone;
|
||||
this._onSetRemoteDescriptionFailure = onError;
|
||||
this._impl.setRemoteDescription(type, sdp);
|
||||
let pp = new Promise(resolve =>
|
||||
this._remoteIdp.verifyIdentityFromSDP(desc.sdp, origin, resolve))
|
||||
.then(msg => {
|
||||
// If this pc has an identity already, then identity in sdp must match
|
||||
if (expectedIdentity && (!msg || msg.identity !== expectedIdentity)) {
|
||||
throw new this._win.DOMException(
|
||||
"Peer Identity mismatch, expected: " + expectedIdentity,
|
||||
"IncompatibleSessionDescriptionError");
|
||||
}
|
||||
if (msg) {
|
||||
// Set new identity and generate an event.
|
||||
this._impl.peerIdentity = msg.identity;
|
||||
this._peerIdentity = new this._win.RTCIdentityAssertion(
|
||||
this._remoteIdp.provider, msg.identity);
|
||||
this.dispatchEvent(new this._win.Event("peeridentity"));
|
||||
}
|
||||
});
|
||||
// Only wait for Idp validation if we need identity matching.
|
||||
return expectedIdentity? this._win.Promise.all([p, pp]).then(() => {}) : p;
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
setIdentityProvider: function(provider, protocol, username) {
|
||||
@ -777,24 +740,21 @@ RTCPeerConnection.prototype = {
|
||||
},
|
||||
|
||||
updateIce: function(config) {
|
||||
throw new this._win.DOMError("NotSupportedError", "updateIce not yet implemented");
|
||||
throw new this._win.DOMException("updateIce not yet implemented",
|
||||
"NotSupportedError");
|
||||
},
|
||||
|
||||
addIceCandidate: function(cand, onSuccess, onError) {
|
||||
if (!cand.candidate && !cand.sdpMLineIndex) {
|
||||
throw new this._win.DOMError("InvalidParameterError",
|
||||
"Invalid candidate passed to addIceCandidate!");
|
||||
}
|
||||
return this._queue(() => this._addIceCandidate(cand), onSuccess, onError);
|
||||
},
|
||||
|
||||
_addIceCandidate: function(cand) {
|
||||
return new this._win.Promise((resolve, reject) => {
|
||||
this._onAddIceCandidateSuccess = resolve;
|
||||
this._onAddIceCandidateError = reject;
|
||||
|
||||
this._impl.addIceCandidate(cand.candidate, cand.sdpMid || "",
|
||||
cand.sdpMLineIndex);
|
||||
addIceCandidate: function(c, onSuccess, onError) {
|
||||
return this._legacyCatch(onSuccess, onError, () => {
|
||||
if (!c.candidate && !c.sdpMLineIndex) {
|
||||
throw new this._win.DOMException("Invalid candidate passed to addIceCandidate!",
|
||||
"InvalidParameterError");
|
||||
}
|
||||
return this._chain(() => new this._win.Promise((resolve, reject) => {
|
||||
this._onAddIceCandidateSuccess = resolve;
|
||||
this._onAddIceCandidateError = reject;
|
||||
this._impl.addIceCandidate(c.candidate, c.sdpMid || "", c.sdpMLineIndex);
|
||||
}));
|
||||
});
|
||||
},
|
||||
|
||||
@ -804,19 +764,22 @@ RTCPeerConnection.prototype = {
|
||||
|
||||
removeStream: function(stream) {
|
||||
// Bug 844295: Not implementing this functionality.
|
||||
throw new this._win.DOMError("NotSupportedError", "removeStream not yet implemented");
|
||||
throw new this._win.DOMException("removeStream not yet implemented",
|
||||
"NotSupportedError");
|
||||
},
|
||||
|
||||
getStreamById: function(id) {
|
||||
throw new this._win.DOMError("NotSupportedError", "getStreamById not yet implemented");
|
||||
throw new this._win.DOMException("getStreamById not yet implemented",
|
||||
"NotSupportedError");
|
||||
},
|
||||
|
||||
addTrack: function(track, stream) {
|
||||
if (stream.currentTime === undefined) {
|
||||
throw new this._win.DOMError("InvalidParameterError", "invalid stream.");
|
||||
throw new this._win.DOMException("invalid stream.", "InvalidParameterError");
|
||||
}
|
||||
if (stream.getTracks().indexOf(track) == -1) {
|
||||
throw new this._win.DOMError("InvalidParameterError", "track is not in stream.");
|
||||
if (stream.getTracks().indexOf(track) < 0) {
|
||||
throw new this._win.DOMException("track is not in stream.",
|
||||
"InvalidParameterError");
|
||||
}
|
||||
this._checkClosed();
|
||||
this._impl.addTrack(track, stream);
|
||||
@ -829,11 +792,12 @@ RTCPeerConnection.prototype = {
|
||||
|
||||
removeTrack: function(sender) {
|
||||
// Bug 844295: Not implementing this functionality.
|
||||
throw new this._win.DOMError("NotSupportedError", "removeTrack not yet implemented");
|
||||
throw new this._win.DOMException("removeTrack not yet implemented",
|
||||
"NotSupportedError");
|
||||
},
|
||||
|
||||
_replaceTrack: function(sender, withTrack) {
|
||||
// TODO: Do a (sender._stream.getTracks().indexOf(track) == -1) check
|
||||
// TODO: Do a (sender._stream.getTracks().indexOf(track) < 0) check
|
||||
// on both track args someday.
|
||||
//
|
||||
// The proposed API will be that both tracks must already be in the same
|
||||
@ -961,14 +925,12 @@ RTCPeerConnection.prototype = {
|
||||
},
|
||||
|
||||
getStats: function(selector, onSuccess, onError) {
|
||||
return this._queue(() => this._getStats(selector), onSuccess, onError);
|
||||
},
|
||||
|
||||
_getStats: function(selector) {
|
||||
return new this._win.Promise((resolve, reject) => {
|
||||
this._onGetStatsSuccess = resolve;
|
||||
this._onGetStatsFailure = reject;
|
||||
this._impl.getStats(selector);
|
||||
return this._legacyCatch(onSuccess, onError, () => {
|
||||
return this._chain(() => new this._win.Promise((resolve, reject) => {
|
||||
this._onGetStatsSuccess = resolve;
|
||||
this._onGetStatsFailure = reject;
|
||||
this._impl.getStats(selector);
|
||||
}));
|
||||
});
|
||||
},
|
||||
|
||||
@ -995,10 +957,10 @@ RTCPeerConnection.prototype = {
|
||||
this.logWarning("Deprecated RTCDataChannelInit dictionary entry stream used!", null, 0);
|
||||
}
|
||||
|
||||
if (dict.maxRetransmitTime != undefined &&
|
||||
dict.maxRetransmits != undefined) {
|
||||
throw new this._win.DOMError("InvalidParameterError",
|
||||
"Both maxRetransmitTime and maxRetransmits cannot be provided");
|
||||
if (dict.maxRetransmitTime !== null && dict.maxRetransmits !== null) {
|
||||
throw new this._win.DOMException(
|
||||
"Both maxRetransmitTime and maxRetransmits cannot be provided",
|
||||
"InvalidParameterError");
|
||||
}
|
||||
let protocol;
|
||||
if (dict.protocol == undefined) {
|
||||
@ -1043,7 +1005,7 @@ PeerConnectionObserver.prototype = {
|
||||
this._dompc = dompc._innerObject;
|
||||
},
|
||||
|
||||
newError: function(code, message) {
|
||||
newError: function(message, code) {
|
||||
// These strings must match those defined in the WebRTC spec.
|
||||
const reasonName = [
|
||||
"",
|
||||
@ -1058,7 +1020,7 @@ PeerConnectionObserver.prototype = {
|
||||
"InternalError"
|
||||
];
|
||||
let name = reasonName[Math.min(code, reasonName.length - 1)];
|
||||
return new this._dompc._win.DOMError(name, message);
|
||||
return new this._dompc._win.DOMException(message, name);
|
||||
},
|
||||
|
||||
dispatchEvent: function(event) {
|
||||
@ -1079,7 +1041,7 @@ PeerConnectionObserver.prototype = {
|
||||
},
|
||||
|
||||
onCreateOfferError: function(code, message) {
|
||||
this._dompc._onCreateOfferFailure(this.newError(code, message));
|
||||
this._dompc._onCreateOfferFailure(this.newError(message, code));
|
||||
},
|
||||
|
||||
onCreateAnswerSuccess: function(sdp) {
|
||||
@ -1096,7 +1058,7 @@ PeerConnectionObserver.prototype = {
|
||||
},
|
||||
|
||||
onCreateAnswerError: function(code, message) {
|
||||
this._dompc._onCreateAnswerFailure(this.newError(code, message));
|
||||
this._dompc._onCreateAnswerFailure(this.newError(message, code));
|
||||
},
|
||||
|
||||
onSetLocalDescriptionSuccess: function() {
|
||||
@ -1109,12 +1071,12 @@ PeerConnectionObserver.prototype = {
|
||||
|
||||
onSetLocalDescriptionError: function(code, message) {
|
||||
this._localType = null;
|
||||
this._dompc._onSetLocalDescriptionFailure(this.newError(code, message));
|
||||
this._dompc._onSetLocalDescriptionFailure(this.newError(message, code));
|
||||
},
|
||||
|
||||
onSetRemoteDescriptionError: function(code, message) {
|
||||
this._remoteType = null;
|
||||
this._dompc._onSetRemoteDescriptionFailure(this.newError(code, message));
|
||||
this._dompc._onSetRemoteDescriptionFailure(this.newError(message, code));
|
||||
},
|
||||
|
||||
onAddIceCandidateSuccess: function() {
|
||||
@ -1122,7 +1084,7 @@ PeerConnectionObserver.prototype = {
|
||||
},
|
||||
|
||||
onAddIceCandidateError: function(code, message) {
|
||||
this._dompc._onAddIceCandidateError(this.newError(code, message));
|
||||
this._dompc._onAddIceCandidateError(this.newError(message, code));
|
||||
},
|
||||
|
||||
onIceCandidate: function(level, mid, candidate) {
|
||||
@ -1250,7 +1212,7 @@ PeerConnectionObserver.prototype = {
|
||||
},
|
||||
|
||||
onGetStatsError: function(code, message) {
|
||||
this._dompc._onGetStatsFailure(this.newError(code, message));
|
||||
this._dompc._onGetStatsFailure(this.newError(message, code));
|
||||
},
|
||||
|
||||
onAddStream: function(stream) {
|
||||
@ -1287,7 +1249,7 @@ PeerConnectionObserver.prototype = {
|
||||
var pc = this._dompc;
|
||||
pc._onReplaceTrackWithTrack = null;
|
||||
pc._onReplaceTrackSender = null;
|
||||
pc._onReplaceTrackError(this.newError(code, message));
|
||||
pc._onReplaceTrackError(this.newError(message, code));
|
||||
},
|
||||
|
||||
foundIceCandidate: function(cand) {
|
||||
@ -1333,7 +1295,7 @@ RTCRtpSender.prototype = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports]),
|
||||
|
||||
replaceTrack: function(withTrack) {
|
||||
return this._pc._queue(() => this._pc._replaceTrack(this, withTrack));
|
||||
return this._pc._chain(() => this._pc._replaceTrack(this, withTrack));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -95,9 +95,12 @@ PeerConnectionIdp.prototype = {
|
||||
|
||||
_getIdentityFromSdp: function(sdp) {
|
||||
// a=identity is session level
|
||||
let idMatch;
|
||||
let mLineMatch = sdp.match(PeerConnectionIdp._mLinePattern);
|
||||
let sessionLevel = sdp.substring(0, mLineMatch.index);
|
||||
let idMatch = sessionLevel.match(PeerConnectionIdp._identityPattern);
|
||||
if (mLineMatch) {
|
||||
let sessionLevel = sdp.substring(0, mLineMatch.index);
|
||||
idMatch = sessionLevel.match(PeerConnectionIdp._identityPattern);
|
||||
}
|
||||
if (idMatch) {
|
||||
let assertion = {};
|
||||
try {
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "mp4_demuxer/DecoderData.h"
|
||||
#include "prlog.h"
|
||||
#include "gfx2DGlue.h"
|
||||
#include "gfxWindowsPlatform.h"
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
PRLogModuleInfo* GetDemuxerLog();
|
||||
@ -149,6 +150,10 @@ WMFVideoMFTManager::InitializeDXVA()
|
||||
return false;
|
||||
}
|
||||
|
||||
if (gfxWindowsPlatform::GetPlatform()->IsWARP()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// The DXVA manager must be created on the main thread.
|
||||
nsRefPtr<CreateDXVAManagerEvent> event(new CreateDXVAManagerEvent());
|
||||
NS_DispatchToMainThread(event, NS_DISPATCH_SYNC);
|
||||
|
@ -22,3 +22,5 @@ UNIFIED_SOURCES += [
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
||||
FAIL_ON_WARNINGS = True
|
||||
|
||||
CXXFLAGS += CONFIG['MOZ_CAIRO_CFLAGS']
|
||||
|
@ -317,7 +317,7 @@ GMPChild::PreLoadLibraries(const std::string& aPluginPath)
|
||||
|
||||
std::ifstream stream;
|
||||
#ifdef _MSC_VER
|
||||
stream.open(path.get());
|
||||
stream.open(static_cast<const wchar_t*>(path.get()));
|
||||
#else
|
||||
stream.open(NS_ConvertUTF16toUTF8(path).get());
|
||||
#endif
|
||||
|
@ -13,10 +13,6 @@ namespace mozilla
|
||||
class MockMediaDecoderOwner : public MediaDecoderOwner
|
||||
{
|
||||
public:
|
||||
virtual nsresult DispatchEvent(const nsAString& aName) MOZ_OVERRIDE
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
virtual nsresult DispatchAsyncEvent(const nsAString& aName) MOZ_OVERRIDE
|
||||
{
|
||||
return NS_OK;
|
||||
|
@ -339,7 +339,7 @@ TrackBuffer::EvictData(double aPlaybackTime,
|
||||
|
||||
bool evicted = toEvict < (totalSize - aThreshold);
|
||||
if (evicted) {
|
||||
nsRefPtr<TimeRanges> ranges = new TimeRanges();
|
||||
nsRefPtr<dom::TimeRanges> ranges = new dom::TimeRanges();
|
||||
mCurrentDecoder->GetBuffered(ranges);
|
||||
*aBufferStartTime = std::max(0.0, ranges->GetStartTime());
|
||||
}
|
||||
|
@ -27,25 +27,25 @@ runWithMSE(function (ms, v) {
|
||||
v.addEventListener("loadedmetadata", function () {
|
||||
v.addEventListener("durationchange", function () {
|
||||
durationChangeCount++;
|
||||
if (durationChangeCount == 1) {
|
||||
sb.addEventListener('updateend', function(e) {
|
||||
sb.removeEventListener('updateend', arguments.callee);
|
||||
sb.appendBuffer(new Uint8Array(arrayBuffer, 318));
|
||||
});
|
||||
}
|
||||
});
|
||||
// Set mediasource duration to 0, so future appendBuffer
|
||||
// will update the mediasource duration
|
||||
// setting ms.duration will fire updatestart/update/updateend
|
||||
// event as per w3c spec
|
||||
// event as per w3c spec followed by a durationchange
|
||||
ms.duration = 0;
|
||||
});
|
||||
} else if (updateCount == 2) {
|
||||
// will fire updatestart/update/updateend
|
||||
// and a durationchange
|
||||
sb.appendBuffer(new Uint8Array(arrayBuffer, 318));
|
||||
} else if (updateCount == 3) {
|
||||
// this will not fire durationchange as new duration == old duration
|
||||
ms.endOfStream();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
v.addEventListener("loadeddata", function () {
|
||||
ms.addEventListener("sourceended", function () {
|
||||
// XXX: Duration should be exactly 4.0, see bug 1065207.
|
||||
is(durationChangeCount, 2, "durationchange not fired as many times as expected");
|
||||
ok(Math.abs(v.duration - 4) <= 0.002, "Video has correct duration");
|
||||
|
@ -251,7 +251,7 @@ LOCAL_INCLUDES += [
|
||||
'/dom/camera',
|
||||
'/layout/generic',
|
||||
'/layout/xul',
|
||||
'/netwerk/base/src',
|
||||
'/netwerk/base',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_DIRECTSHOW']:
|
||||
|
@ -511,9 +511,13 @@ bool MediaCodecProxy::Prepare()
|
||||
|
||||
bool MediaCodecProxy::UpdateOutputBuffers()
|
||||
{
|
||||
if (mCodec == nullptr) {
|
||||
MCP_LOG("MediaCodec has not been inited from input!");
|
||||
return false;
|
||||
// Read Lock for mCodec
|
||||
{
|
||||
RWLock::AutoRLock autolock(mCodecLock);
|
||||
if (mCodec == nullptr) {
|
||||
MCP_LOG("MediaCodec has not been inited from UpdateOutputBuffers");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
status_t err = getOutputBuffers(&mOutputBuffers);
|
||||
@ -527,9 +531,13 @@ bool MediaCodecProxy::UpdateOutputBuffers()
|
||||
status_t MediaCodecProxy::Input(const uint8_t* aData, uint32_t aDataSize,
|
||||
int64_t aTimestampUsecs, uint64_t aflags)
|
||||
{
|
||||
if (mCodec == nullptr) {
|
||||
MCP_LOG("MediaCodec has not been inited from input!");
|
||||
return NO_INIT;
|
||||
// Read Lock for mCodec
|
||||
{
|
||||
RWLock::AutoRLock autolock(mCodecLock);
|
||||
if (mCodec == nullptr) {
|
||||
MCP_LOG("MediaCodec has not been inited from input!");
|
||||
return NO_INIT;
|
||||
}
|
||||
}
|
||||
|
||||
size_t index;
|
||||
@ -560,9 +568,13 @@ status_t MediaCodecProxy::Input(const uint8_t* aData, uint32_t aDataSize,
|
||||
|
||||
status_t MediaCodecProxy::Output(MediaBuffer** aBuffer, int64_t aTimeoutUs)
|
||||
{
|
||||
if (mCodec == nullptr) {
|
||||
MCP_LOG("MediaCodec has not been inited from output!");
|
||||
return NO_INIT;
|
||||
// Read Lock for mCodec
|
||||
{
|
||||
RWLock::AutoRLock autolock(mCodecLock);
|
||||
if (mCodec == nullptr) {
|
||||
MCP_LOG("MediaCodec has not been inited from output!");
|
||||
return NO_INIT;
|
||||
}
|
||||
}
|
||||
|
||||
size_t index = 0;
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "MediaStreamSource.h"
|
||||
#include "MediaTaskQueue.h"
|
||||
#include "MP3FrameParser.h"
|
||||
#include "nsMimeTypes.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "ImageContainer.h"
|
||||
#include "SharedThreadPool.h"
|
||||
@ -688,7 +689,9 @@ MediaCodecReader::ReadMetadata(MediaInfo* aInfo,
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (!TriggerIncrementalParser()) {
|
||||
bool incrementalParserNeeded =
|
||||
mDecoder->GetResource()->GetContentType().EqualsASCII(AUDIO_MP3);
|
||||
if (incrementalParserNeeded && !TriggerIncrementalParser()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
@ -1419,10 +1422,10 @@ MediaCodecReader::TriggerIncrementalParser()
|
||||
mParsedDataLength = INT64_C(0);
|
||||
|
||||
// MP3 file duration
|
||||
mMP3FrameParser = new MP3FrameParser(mDecoder->GetResource()->GetLength());
|
||||
const char* mime = nullptr;
|
||||
if (mMetaData->findCString(kKeyMIMEType, &mime) &&
|
||||
!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
|
||||
mMP3FrameParser = new MP3FrameParser(mDecoder->GetResource()->GetLength());
|
||||
{
|
||||
MonitorAutoUnlock monUnlock(mParserMonitor);
|
||||
// trigger parsing logic and wait for finishing parsing data in the beginning.
|
||||
|
@ -26,14 +26,14 @@
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
// For M_PI from cmath
|
||||
#ifdef _MSC_VER
|
||||
# define _USE_MATH_DEFINES
|
||||
#endif
|
||||
// For M_PI
|
||||
// VS2015 requires <math.h> to be used; <cmath> doesn't seem to honor
|
||||
// _USE_MATH_DEFINES.
|
||||
#define _USE_MATH_DEFINES
|
||||
#include <math.h>
|
||||
|
||||
#include "Biquad.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <float.h>
|
||||
#include <algorithm>
|
||||
|
||||
|
@ -32,7 +32,7 @@ using dom::ConstrainLongRange;
|
||||
NS_IMPL_ISUPPORTS(MediaEngineTabVideoSource, nsIDOMEventListener, nsITimerCallback)
|
||||
|
||||
MediaEngineTabVideoSource::MediaEngineTabVideoSource()
|
||||
: mMonitor("MediaEngineTabVideoSource"), mTabSource(nullptr)
|
||||
: mData(NULL), mDataSize(0), mMonitor("MediaEngineTabVideoSource"), mTabSource(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
@ -79,7 +79,6 @@ MediaEngineTabVideoSource::Notify(nsITimer*) {
|
||||
nsresult
|
||||
MediaEngineTabVideoSource::InitRunnable::Run()
|
||||
{
|
||||
mVideoSource->mData = (unsigned char*)malloc(mVideoSource->mBufW * mVideoSource->mBufH * 4);
|
||||
if (mVideoSource->mWindowId != -1) {
|
||||
nsCOMPtr<nsPIDOMWindow> window = nsGlobalWindow::GetOuterWindowWithId(mVideoSource->mWindowId);
|
||||
if (window) {
|
||||
@ -150,20 +149,10 @@ MediaEngineTabVideoSource::Allocate(const VideoTrackConstraintsN& aConstraints,
|
||||
}
|
||||
}
|
||||
|
||||
mBufW = aPrefs.GetWidth(false);
|
||||
mBufH = aPrefs.GetHeight(false);
|
||||
ConstrainLongRange defaultRange;
|
||||
|
||||
if (cWidth.mMin > mBufW) {
|
||||
mBufW = cWidth.mMin;
|
||||
} else if (cWidth.mMax < mBufW) {
|
||||
mBufW = cWidth.mMax;
|
||||
}
|
||||
|
||||
if (cHeight.mMin > mBufH) {
|
||||
mBufH = cHeight.mMin;
|
||||
} else if (cHeight.mMax < mBufH) {
|
||||
mBufH = cHeight.mMax;
|
||||
}
|
||||
mBufWidthMax = defaultRange.mMax > cWidth.mMax ? cWidth.mMax : aPrefs.GetWidth(false);
|
||||
mBufHeightMax = defaultRange.mMax > cHeight.mMax ? cHeight.mMax : aPrefs.GetHeight(false);
|
||||
|
||||
mTimePerFrame = aPrefs.mFPS ? 1000 / aPrefs.mFPS : aPrefs.mFPS;
|
||||
return NS_OK;
|
||||
@ -213,35 +202,38 @@ MediaEngineTabVideoSource::NotifyPull(MediaStreamGraph*,
|
||||
|
||||
void
|
||||
MediaEngineTabVideoSource::Draw() {
|
||||
|
||||
IntSize size(mBufW, mBufH);
|
||||
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(mWindow);
|
||||
|
||||
if (!win) {
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t width, height;
|
||||
win->GetInnerWidth(&width);
|
||||
win->GetInnerHeight(&height);
|
||||
int32_t innerWidth, innerHeight;
|
||||
win->GetInnerWidth(&innerWidth);
|
||||
win->GetInnerHeight(&innerHeight);
|
||||
|
||||
if (width == 0 || height == 0) {
|
||||
if (innerWidth == 0 || innerHeight == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t srcW;
|
||||
int32_t srcH;
|
||||
|
||||
float aspectRatio = ((float) size.width) / size.height;
|
||||
if (width / aspectRatio < height) {
|
||||
srcW = width;
|
||||
srcH = width / aspectRatio;
|
||||
IntSize size;
|
||||
// maintain source aspect ratio
|
||||
if (mBufWidthMax/innerWidth < mBufHeightMax/innerHeight) {
|
||||
size = IntSize(mBufWidthMax, (mBufWidthMax * ((float) innerHeight/innerWidth)));
|
||||
} else {
|
||||
srcW = height * aspectRatio;
|
||||
srcH = height;
|
||||
size = IntSize((mBufHeightMax * ((float) innerWidth/innerHeight)), mBufHeightMax);
|
||||
}
|
||||
|
||||
gfxImageFormat format = gfxImageFormat::RGB24;
|
||||
uint32_t stride = gfxASurface::FormatStrideForWidth(format, size.width);
|
||||
|
||||
if (mDataSize < static_cast<size_t>(stride * size.height)) {
|
||||
mDataSize = stride * size.height;
|
||||
mData = static_cast<unsigned char*>(malloc(mDataSize));
|
||||
}
|
||||
|
||||
if (!mData) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<nsPresContext> presContext;
|
||||
@ -259,11 +251,8 @@ MediaEngineTabVideoSource::Draw() {
|
||||
if (!mScrollWithPage) {
|
||||
renderDocFlags |= nsIPresShell::RENDER_IGNORE_VIEWPORT_SCROLLING;
|
||||
}
|
||||
nsRect r(0, 0, nsPresContext::CSSPixelsToAppUnits((float)srcW),
|
||||
nsPresContext::CSSPixelsToAppUnits((float)srcH));
|
||||
|
||||
gfxImageFormat format = gfxImageFormat::RGB24;
|
||||
uint32_t stride = gfxASurface::FormatStrideForWidth(format, size.width);
|
||||
nsRect r(0, 0, nsPresContext::CSSPixelsToAppUnits((float)innerWidth),
|
||||
nsPresContext::CSSPixelsToAppUnits((float)innerHeight));
|
||||
|
||||
nsRefPtr<layers::ImageContainer> container = layers::LayerManager::CreateImageContainer();
|
||||
RefPtr<DrawTarget> dt =
|
||||
@ -276,12 +265,10 @@ MediaEngineTabVideoSource::Draw() {
|
||||
return;
|
||||
}
|
||||
nsRefPtr<gfxContext> context = new gfxContext(dt);
|
||||
context->SetMatrix(context->CurrentMatrix().Scale((float)size.width/srcW,
|
||||
(float)size.height/srcH));
|
||||
context->SetMatrix(context->CurrentMatrix().Scale((((float) size.width)/innerWidth),
|
||||
(((float) size.height)/innerHeight)));
|
||||
|
||||
rv = presShell->RenderDocument(r, renderDocFlags, bgColor, context);
|
||||
|
||||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
NS_ENSURE_SUCCESS_VOID(presShell->RenderDocument(r, renderDocFlags, bgColor, context));
|
||||
|
||||
RefPtr<SourceSurface> surface = dt->Snapshot();
|
||||
if (!surface) {
|
||||
|
@ -70,12 +70,13 @@ protected:
|
||||
~MediaEngineTabVideoSource() {}
|
||||
|
||||
private:
|
||||
int mBufW;
|
||||
int mBufH;
|
||||
int mBufWidthMax;
|
||||
int mBufHeightMax;
|
||||
int64_t mWindowId;
|
||||
bool mScrollWithPage;
|
||||
int mTimePerFrame;
|
||||
ScopedFreePtr<unsigned char> mData;
|
||||
size_t mDataSize;
|
||||
nsCOMPtr<nsIDOMWindow> mWindow;
|
||||
nsRefPtr<layers::CairoImage> mImage;
|
||||
nsCOMPtr<nsITimer> mTimer;
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "ImageContainer.h"
|
||||
#include "Layers.h"
|
||||
#include "mozilla/layers/LayersTypes.h"
|
||||
#include "gfxWindowsPlatform.h"
|
||||
|
||||
#ifndef MOZ_SAMPLE_TYPE_FLOAT32
|
||||
#error We expect 32bit float audio samples on desktop for the Windows Media Foundation media backend.
|
||||
@ -110,6 +111,10 @@ WMFReader::InitializeDXVA()
|
||||
return false;
|
||||
}
|
||||
|
||||
if (gfxWindowsPlatform::GetPlatform()->IsWARP()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mDXVA2Manager = DXVA2Manager::Create();
|
||||
|
||||
return mDXVA2Manager != nullptr;
|
||||
|
@ -30,3 +30,5 @@ FINAL_LIBRARY = 'xul'
|
||||
|
||||
if CONFIG['OS_ARCH'] == 'WINNT':
|
||||
DEFINES['NOMINMAX'] = True
|
||||
|
||||
CXXFLAGS += CONFIG['MOZ_CAIRO_CFLAGS']
|
||||
|
@ -29,5 +29,5 @@ FAIL_ON_WARNINGS = True
|
||||
FINAL_LIBRARY = 'xul'
|
||||
LOCAL_INCLUDES += [
|
||||
'/caps',
|
||||
'/netwerk/base/src',
|
||||
'/netwerk/base',
|
||||
]
|
||||
|
@ -11179,248 +11179,250 @@
|
||||
46753a52402,52403
|
||||
> terahertz/M
|
||||
> terapixel/MS
|
||||
46806,46807c52456
|
||||
46756a52407
|
||||
> teriyaki
|
||||
46806,46807c52457
|
||||
< test's/AFK
|
||||
< test/AKFCDGS
|
||||
---
|
||||
> test/AKFCDGSM
|
||||
46817a52467
|
||||
46817a52468
|
||||
> testcase/MS
|
||||
46831a52482
|
||||
46831a52483
|
||||
> testsuite/MS
|
||||
46845a52497
|
||||
46845a52498
|
||||
> textbox/SM
|
||||
46925a52578
|
||||
46925a52579
|
||||
> theremin/MS
|
||||
46999c52652
|
||||
46999c52653
|
||||
< thinking's
|
||||
---
|
||||
> thinking/M
|
||||
47095,47096c52748
|
||||
47095,47096c52749
|
||||
< throne's
|
||||
< throne/CDS
|
||||
---
|
||||
> throne/CDSM
|
||||
47188,47189c52840
|
||||
47188,47189c52841
|
||||
< tie's
|
||||
< tie/AUSD
|
||||
---
|
||||
> tie/AUSDM
|
||||
47213,47214c52864
|
||||
47213,47214c52865
|
||||
< till's
|
||||
< till/EDRZGS
|
||||
---
|
||||
> till/EDRZGSM
|
||||
47303,47304c52953
|
||||
47303,47304c52954
|
||||
< tire's
|
||||
< tire/AGDS
|
||||
---
|
||||
> tire/AGDSM
|
||||
47433,47434c53082
|
||||
47433,47434c53083
|
||||
< tone's
|
||||
< tone/IZGDRS
|
||||
---
|
||||
> tone/IZGDRSM
|
||||
47453,47455c53101,53102
|
||||
47453,47455c53102,53103
|
||||
< tool's
|
||||
< tool/ADGS
|
||||
< toolbar
|
||||
---
|
||||
> tool/ADGSM
|
||||
> toolbar/MS
|
||||
47540,47541c53187
|
||||
47540,47541c53188
|
||||
< tort's
|
||||
< tort/FEAS
|
||||
---
|
||||
> tort/FEASM
|
||||
47644a53291
|
||||
47644a53292
|
||||
> traceur/SM
|
||||
47657,47658c53304
|
||||
47657,47658c53305
|
||||
< tract's
|
||||
< tract/CEKFAS
|
||||
---
|
||||
> tract/CEKFASM
|
||||
47755a53402
|
||||
47755a53403
|
||||
> transfect/DSMG
|
||||
47774a53422,53423
|
||||
47774a53423,53424
|
||||
> transgenderism
|
||||
> transgene/MS
|
||||
47807,47808c53456
|
||||
47807,47808c53457
|
||||
< transmission's
|
||||
< transmission/AS
|
||||
---
|
||||
> transmission/ASM
|
||||
47928,47929c53576
|
||||
47928,47929c53577
|
||||
< trench's
|
||||
< trench/AIGSD
|
||||
---
|
||||
> trench/AIGSDM
|
||||
47951c53598
|
||||
47951c53599
|
||||
< triage/M
|
||||
---
|
||||
> triage/MGS
|
||||
47976,47977c53623
|
||||
47976,47977c53624
|
||||
< tribute's
|
||||
< tribute/FS
|
||||
---
|
||||
> tribute/FSM
|
||||
47997a53644
|
||||
47997a53645
|
||||
> trifecta/S
|
||||
48165,48166c53812
|
||||
48165,48166c53813
|
||||
< trust's/E
|
||||
< trust/IESGD
|
||||
---
|
||||
> trust/IESGDM
|
||||
48180,48181c53826
|
||||
48180,48181c53827
|
||||
< try's
|
||||
< try/AGDS
|
||||
---
|
||||
> try/AGDSM
|
||||
48271a53917
|
||||
48271a53918
|
||||
> turducken
|
||||
48334a53981
|
||||
48334a53982
|
||||
> tweep/S
|
||||
48371,48372c54018
|
||||
48371,48372c54019
|
||||
< twist's
|
||||
< twist/USDG
|
||||
---
|
||||
> twist/USDGM
|
||||
48396,48397c54042
|
||||
48396,48397c54043
|
||||
< type's
|
||||
< type/AGDS
|
||||
---
|
||||
> type/AGDSM
|
||||
48869a54515
|
||||
48869a54516
|
||||
> unlikeable
|
||||
49163,49164c54809
|
||||
49163,49164c54810
|
||||
< usual's
|
||||
< usual/UY
|
||||
---
|
||||
> usual/UYM
|
||||
49211c54856
|
||||
49211c54857
|
||||
< vagina/M
|
||||
---
|
||||
> vagina/MS
|
||||
49249,49250c54894
|
||||
49249,49250c54895
|
||||
< value's
|
||||
< value/CAGSD
|
||||
---
|
||||
> value/CAGSDM
|
||||
49292,49293c54936
|
||||
49292,49293c54937
|
||||
< variant's
|
||||
< variant/IS
|
||||
---
|
||||
> variant/ISM
|
||||
49356,49357c54999
|
||||
49356,49357c55000
|
||||
< veil's
|
||||
< veil/UDGS
|
||||
---
|
||||
> veil/UDGSM
|
||||
49368,49369c55010
|
||||
49368,49369c55011
|
||||
< velour's
|
||||
< velours's
|
||||
---
|
||||
> velour/MS
|
||||
49398,49399c55039
|
||||
49398,49399c55040
|
||||
< vent's
|
||||
< vent/DGS
|
||||
---
|
||||
> vent/DGSM
|
||||
49435,49436c55075
|
||||
49435,49436c55076
|
||||
< verge's
|
||||
< verge/FDSG
|
||||
---
|
||||
> verge/FDSGM
|
||||
49478a55118
|
||||
49478a55119
|
||||
> vertices
|
||||
49488,49489c55128
|
||||
49488,49489c55129
|
||||
< vest's
|
||||
< vest/ILDGS
|
||||
---
|
||||
> vest/ILDGSM
|
||||
49681,49682c55320
|
||||
49681,49682c55321
|
||||
< visit's
|
||||
< visit/ASGD
|
||||
---
|
||||
> visit/ASGDM
|
||||
49772a55411,55413
|
||||
49772a55412,55414
|
||||
> volcanological
|
||||
> volcanologist/MS
|
||||
> volcanology/M
|
||||
49807,49808c55448
|
||||
49807,49808c55449
|
||||
< vote's
|
||||
< vote/CGVDS
|
||||
---
|
||||
> vote/CGVDSM
|
||||
50148a55789
|
||||
50148a55790
|
||||
> weaponize/DSG
|
||||
50215,50216c55856
|
||||
50215,50216c55857
|
||||
< weigh's
|
||||
< weigh/AGD
|
||||
---
|
||||
> weigh/AGDM
|
||||
50260,50261d55899
|
||||
50260,50261d55900
|
||||
< werwolf/M
|
||||
< werwolves
|
||||
50555,50556c56193
|
||||
50555,50556c56194
|
||||
< wind's
|
||||
< wind/UASG
|
||||
---
|
||||
> wind/UASGM
|
||||
50626,50627c56263
|
||||
50626,50627c56264
|
||||
< wire's
|
||||
< wire/AGDS
|
||||
---
|
||||
> wire/AGDSM
|
||||
50728c56364
|
||||
50728c56365
|
||||
< women
|
||||
---
|
||||
> women/M
|
||||
50794,50796c56430,56431
|
||||
50794,50796c56431,56432
|
||||
< wop/S!
|
||||
< word's
|
||||
< word/AJDSG
|
||||
---
|
||||
> wop/MS!
|
||||
> word/AJDSGM
|
||||
50801c56436
|
||||
50801c56437
|
||||
< wording's
|
||||
---
|
||||
> wording/M
|
||||
50808,50809c56443
|
||||
50808,50809c56444
|
||||
< work's
|
||||
< work/ADJSG
|
||||
---
|
||||
> work/ADJSGM
|
||||
50824c56458
|
||||
50824c56459
|
||||
< working's
|
||||
---
|
||||
> working/M
|
||||
50884,50885c56518
|
||||
50884,50885c56519
|
||||
< worthy's
|
||||
< worthy/UPRT
|
||||
---
|
||||
> worthy/UPRTM
|
||||
50903,50904c56536
|
||||
50903,50904c56537
|
||||
< wrap's
|
||||
< wrap/US
|
||||
---
|
||||
> wrap/USM
|
||||
50945c56577
|
||||
50945c56578
|
||||
< writing's
|
||||
---
|
||||
> writing/M
|
||||
51118,51119c56750
|
||||
51118,51119c56751
|
||||
< yoke's
|
||||
< yoke/UGDS
|
||||
---
|
||||
> yoke/UGDSM
|
||||
51212,51213c56843
|
||||
51212,51213c56844
|
||||
< zip's
|
||||
< zip/US
|
||||
---
|
||||
> zip/USM
|
||||
51228,51229c56858
|
||||
51228,51229c56859
|
||||
< zone's
|
||||
< zone/AGDS
|
||||
---
|
||||
|
@ -1,4 +1,4 @@
|
||||
57245
|
||||
57246
|
||||
0/nm
|
||||
0th/pt
|
||||
1/n1
|
||||
@ -52757,6 +52757,7 @@ terapixel/MS
|
||||
terbium/M
|
||||
tercentenary/SM
|
||||
tercentennial/MS
|
||||
teriyaki
|
||||
term/MDYGS
|
||||
termagant/MS
|
||||
terminable/IC
|
||||
|
@ -12,7 +12,7 @@
|
||||
#include <fstream>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#include <hash_set>
|
||||
#include <unordered_set>
|
||||
#else
|
||||
#include <set>
|
||||
#endif
|
||||
@ -53,7 +53,7 @@ protected:
|
||||
virtual void Flush() = 0;
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
typedef stdext::hash_set<const void*> ObjectSet;
|
||||
typedef std::unordered_set<const void*> ObjectSet;
|
||||
#else
|
||||
typedef std::set<const void*> ObjectSet;
|
||||
#endif
|
||||
|
@ -14,11 +14,7 @@
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <hash_set>
|
||||
#else
|
||||
#include <unordered_set>
|
||||
#endif
|
||||
|
||||
struct IDWriteFactory;
|
||||
|
||||
@ -165,11 +161,7 @@ private:
|
||||
friend class AutoSaveRestoreClippedOut;
|
||||
friend class SourceSurfaceD2DTarget;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
typedef stdext::hash_set<DrawTargetD2D*> TargetSet;
|
||||
#else
|
||||
typedef std::unordered_set<DrawTargetD2D*> TargetSet;
|
||||
#endif
|
||||
|
||||
bool InitD2DRenderTarget();
|
||||
void PrepareForDrawing(ID2D1RenderTarget *aRT);
|
||||
|
@ -15,11 +15,7 @@
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <hash_set>
|
||||
#else
|
||||
#include <unordered_set>
|
||||
#endif
|
||||
|
||||
struct IDWriteFactory;
|
||||
|
||||
@ -154,11 +150,7 @@ public:
|
||||
private:
|
||||
friend class SourceSurfaceD2D1;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
typedef stdext::hash_set<DrawTargetD2D1*> TargetSet;
|
||||
#else
|
||||
typedef std::unordered_set<DrawTargetD2D1*> TargetSet;
|
||||
#endif
|
||||
|
||||
// This function will mark the surface as changing, and make sure any
|
||||
// copy-on-write snapshots are notified.
|
||||
|
@ -1,4 +1,5 @@
|
||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim:set ts=4 sw=4 sts=4 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
@ -365,6 +366,8 @@ StaticAutoPtr<LayerScopeWebSocketManager> WebSocketHelper::sWebSocketManager;
|
||||
* 1. DebugGLFrameStatusData (Frame start/end packet)
|
||||
* 2. DebugGLColorData (Color data packet)
|
||||
* 3. DebugGLTextureData (Texture data packet)
|
||||
* 4. DebugGLLayersData (Layers Tree data packet)
|
||||
* 5. DebugGLMetaData (Meta data packet)
|
||||
*/
|
||||
class DebugGLData: public LinkedListElement<DebugGLData> {
|
||||
public:
|
||||
@ -566,6 +569,37 @@ protected:
|
||||
UniquePtr<Packet> mPacket;
|
||||
};
|
||||
|
||||
class DebugGLMetaData : public DebugGLData
|
||||
{
|
||||
public:
|
||||
DebugGLMetaData(Packet::DataType aDataType,
|
||||
bool aValue)
|
||||
: DebugGLData(aDataType),
|
||||
mComposedByHwc(aValue)
|
||||
{ }
|
||||
|
||||
explicit DebugGLMetaData(Packet::DataType aDataType)
|
||||
: DebugGLData(aDataType),
|
||||
mComposedByHwc(false)
|
||||
{ }
|
||||
|
||||
virtual bool Write() MOZ_OVERRIDE {
|
||||
Packet packet;
|
||||
packet.set_type(mDataType);
|
||||
|
||||
MetaPacket* mp = packet.mutable_meta();
|
||||
mp->set_composedbyhwc(mComposedByHwc);
|
||||
|
||||
if (!WriteToStream(packet))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
bool mComposedByHwc;
|
||||
};
|
||||
|
||||
|
||||
class DebugListener : public nsIServerSocketListener
|
||||
{
|
||||
virtual ~DebugListener() { }
|
||||
@ -1005,6 +1039,16 @@ LayerScope::CleanLayer()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LayerScope::SetHWComposed()
|
||||
{
|
||||
if (CheckSendable()) {
|
||||
WebSocketHelper::GetSocketManager()->AppendDebugData(
|
||||
new DebugGLMetaData(Packet::META, true));
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------
|
||||
// LayerScopeAutoFrame implementation
|
||||
// ----------------------------------------------
|
||||
|
@ -1,4 +1,5 @@
|
||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim:set ts=4 sw=4 sts=4 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
@ -34,6 +35,7 @@ public:
|
||||
static void SendLayerDump(UniquePtr<layerscope::Packet> aPacket);
|
||||
static bool CheckSendable();
|
||||
static void CleanLayer();
|
||||
static void SetHWComposed();
|
||||
|
||||
private:
|
||||
static void Init();
|
||||
|
@ -662,6 +662,7 @@ LayerManagerComposite::Render()
|
||||
}
|
||||
|
||||
if (!mTarget && composer2D && composer2D->TryRender(mRoot, mGeometryChanged)) {
|
||||
LayerScope::SetHWComposed();
|
||||
if (mFPS) {
|
||||
double fps = mFPS->mCompositionFps.AddFrameAndGetFps(TimeStamp::Now());
|
||||
if (gfxPrefs::LayersDrawFPS()) {
|
||||
|
@ -25,6 +25,7 @@ void protobuf_ShutdownFile_LayerScopePacket_2eproto() {
|
||||
delete LayersPacket_Layer_Region::default_instance_;
|
||||
delete LayersPacket_Layer_Matrix::default_instance_;
|
||||
delete LayersPacket_Layer_Shadow::default_instance_;
|
||||
delete MetaPacket::default_instance_;
|
||||
delete Packet::default_instance_;
|
||||
}
|
||||
|
||||
@ -44,6 +45,7 @@ void protobuf_AddDesc_LayerScopePacket_2eproto() {
|
||||
LayersPacket_Layer_Region::default_instance_ = new LayersPacket_Layer_Region();
|
||||
LayersPacket_Layer_Matrix::default_instance_ = new LayersPacket_Layer_Matrix();
|
||||
LayersPacket_Layer_Shadow::default_instance_ = new LayersPacket_Layer_Shadow();
|
||||
MetaPacket::default_instance_ = new MetaPacket();
|
||||
Packet::default_instance_ = new Packet();
|
||||
FramePacket::default_instance_->InitAsDefaultInstance();
|
||||
ColorPacket::default_instance_->InitAsDefaultInstance();
|
||||
@ -55,6 +57,7 @@ void protobuf_AddDesc_LayerScopePacket_2eproto() {
|
||||
LayersPacket_Layer_Region::default_instance_->InitAsDefaultInstance();
|
||||
LayersPacket_Layer_Matrix::default_instance_->InitAsDefaultInstance();
|
||||
LayersPacket_Layer_Shadow::default_instance_->InitAsDefaultInstance();
|
||||
MetaPacket::default_instance_->InitAsDefaultInstance();
|
||||
Packet::default_instance_->InitAsDefaultInstance();
|
||||
::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_LayerScopePacket_2eproto);
|
||||
}
|
||||
@ -3028,6 +3031,162 @@ void LayersPacket::Swap(LayersPacket* other) {
|
||||
}
|
||||
|
||||
|
||||
// ===================================================================
|
||||
|
||||
#ifndef _MSC_VER
|
||||
const int MetaPacket::kComposedByHwcFieldNumber;
|
||||
#endif // !_MSC_VER
|
||||
|
||||
MetaPacket::MetaPacket()
|
||||
: ::google::protobuf::MessageLite() {
|
||||
SharedCtor();
|
||||
}
|
||||
|
||||
void MetaPacket::InitAsDefaultInstance() {
|
||||
}
|
||||
|
||||
MetaPacket::MetaPacket(const MetaPacket& from)
|
||||
: ::google::protobuf::MessageLite() {
|
||||
SharedCtor();
|
||||
MergeFrom(from);
|
||||
}
|
||||
|
||||
void MetaPacket::SharedCtor() {
|
||||
_cached_size_ = 0;
|
||||
composedbyhwc_ = false;
|
||||
::memset(_has_bits_, 0, sizeof(_has_bits_));
|
||||
}
|
||||
|
||||
MetaPacket::~MetaPacket() {
|
||||
SharedDtor();
|
||||
}
|
||||
|
||||
void MetaPacket::SharedDtor() {
|
||||
if (this != default_instance_) {
|
||||
}
|
||||
}
|
||||
|
||||
void MetaPacket::SetCachedSize(int size) const {
|
||||
GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
|
||||
_cached_size_ = size;
|
||||
GOOGLE_SAFE_CONCURRENT_WRITES_END();
|
||||
}
|
||||
const MetaPacket& MetaPacket::default_instance() {
|
||||
if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto(); return *default_instance_;
|
||||
}
|
||||
|
||||
MetaPacket* MetaPacket::default_instance_ = NULL;
|
||||
|
||||
MetaPacket* MetaPacket::New() const {
|
||||
return new MetaPacket;
|
||||
}
|
||||
|
||||
void MetaPacket::Clear() {
|
||||
if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
|
||||
composedbyhwc_ = false;
|
||||
}
|
||||
::memset(_has_bits_, 0, sizeof(_has_bits_));
|
||||
}
|
||||
|
||||
bool MetaPacket::MergePartialFromCodedStream(
|
||||
::google::protobuf::io::CodedInputStream* input) {
|
||||
#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
|
||||
::google::protobuf::uint32 tag;
|
||||
while ((tag = input->ReadTag()) != 0) {
|
||||
switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
|
||||
// optional bool composedByHwc = 1;
|
||||
case 1: {
|
||||
if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
|
||||
::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
|
||||
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
|
||||
bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
|
||||
input, &composedbyhwc_)));
|
||||
set_has_composedbyhwc();
|
||||
} else {
|
||||
goto handle_uninterpreted;
|
||||
}
|
||||
if (input->ExpectAtEnd()) return true;
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
handle_uninterpreted:
|
||||
if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
|
||||
::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
|
||||
return true;
|
||||
}
|
||||
DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
#undef DO_
|
||||
}
|
||||
|
||||
void MetaPacket::SerializeWithCachedSizes(
|
||||
::google::protobuf::io::CodedOutputStream* output) const {
|
||||
// optional bool composedByHwc = 1;
|
||||
if (has_composedbyhwc()) {
|
||||
::google::protobuf::internal::WireFormatLite::WriteBool(1, this->composedbyhwc(), output);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int MetaPacket::ByteSize() const {
|
||||
int total_size = 0;
|
||||
|
||||
if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
|
||||
// optional bool composedByHwc = 1;
|
||||
if (has_composedbyhwc()) {
|
||||
total_size += 1 + 1;
|
||||
}
|
||||
|
||||
}
|
||||
GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
|
||||
_cached_size_ = total_size;
|
||||
GOOGLE_SAFE_CONCURRENT_WRITES_END();
|
||||
return total_size;
|
||||
}
|
||||
|
||||
void MetaPacket::CheckTypeAndMergeFrom(
|
||||
const ::google::protobuf::MessageLite& from) {
|
||||
MergeFrom(*::google::protobuf::down_cast<const MetaPacket*>(&from));
|
||||
}
|
||||
|
||||
void MetaPacket::MergeFrom(const MetaPacket& from) {
|
||||
GOOGLE_CHECK_NE(&from, this);
|
||||
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
|
||||
if (from.has_composedbyhwc()) {
|
||||
set_composedbyhwc(from.composedbyhwc());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MetaPacket::CopyFrom(const MetaPacket& from) {
|
||||
if (&from == this) return;
|
||||
Clear();
|
||||
MergeFrom(from);
|
||||
}
|
||||
|
||||
bool MetaPacket::IsInitialized() const {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void MetaPacket::Swap(MetaPacket* other) {
|
||||
if (other != this) {
|
||||
std::swap(composedbyhwc_, other->composedbyhwc_);
|
||||
std::swap(_has_bits_[0], other->_has_bits_[0]);
|
||||
std::swap(_cached_size_, other->_cached_size_);
|
||||
}
|
||||
}
|
||||
|
||||
::std::string MetaPacket::GetTypeName() const {
|
||||
return "mozilla.layers.layerscope.MetaPacket";
|
||||
}
|
||||
|
||||
|
||||
// ===================================================================
|
||||
|
||||
bool Packet_DataType_IsValid(int value) {
|
||||
@ -3037,6 +3196,7 @@ bool Packet_DataType_IsValid(int value) {
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
@ -3049,6 +3209,7 @@ const Packet_DataType Packet::FRAMEEND;
|
||||
const Packet_DataType Packet::COLOR;
|
||||
const Packet_DataType Packet::TEXTURE;
|
||||
const Packet_DataType Packet::LAYERS;
|
||||
const Packet_DataType Packet::META;
|
||||
const Packet_DataType Packet::DataType_MIN;
|
||||
const Packet_DataType Packet::DataType_MAX;
|
||||
const int Packet::DataType_ARRAYSIZE;
|
||||
@ -3059,6 +3220,7 @@ const int Packet::kFrameFieldNumber;
|
||||
const int Packet::kColorFieldNumber;
|
||||
const int Packet::kTextureFieldNumber;
|
||||
const int Packet::kLayersFieldNumber;
|
||||
const int Packet::kMetaFieldNumber;
|
||||
#endif // !_MSC_VER
|
||||
|
||||
Packet::Packet()
|
||||
@ -3071,6 +3233,7 @@ void Packet::InitAsDefaultInstance() {
|
||||
color_ = const_cast< ::mozilla::layers::layerscope::ColorPacket*>(&::mozilla::layers::layerscope::ColorPacket::default_instance());
|
||||
texture_ = const_cast< ::mozilla::layers::layerscope::TexturePacket*>(&::mozilla::layers::layerscope::TexturePacket::default_instance());
|
||||
layers_ = const_cast< ::mozilla::layers::layerscope::LayersPacket*>(&::mozilla::layers::layerscope::LayersPacket::default_instance());
|
||||
meta_ = const_cast< ::mozilla::layers::layerscope::MetaPacket*>(&::mozilla::layers::layerscope::MetaPacket::default_instance());
|
||||
}
|
||||
|
||||
Packet::Packet(const Packet& from)
|
||||
@ -3086,6 +3249,7 @@ void Packet::SharedCtor() {
|
||||
color_ = NULL;
|
||||
texture_ = NULL;
|
||||
layers_ = NULL;
|
||||
meta_ = NULL;
|
||||
::memset(_has_bits_, 0, sizeof(_has_bits_));
|
||||
}
|
||||
|
||||
@ -3099,6 +3263,7 @@ void Packet::SharedDtor() {
|
||||
delete color_;
|
||||
delete texture_;
|
||||
delete layers_;
|
||||
delete meta_;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3132,6 +3297,9 @@ void Packet::Clear() {
|
||||
if (has_layers()) {
|
||||
if (layers_ != NULL) layers_->::mozilla::layers::layerscope::LayersPacket::Clear();
|
||||
}
|
||||
if (has_meta()) {
|
||||
if (meta_ != NULL) meta_->::mozilla::layers::layerscope::MetaPacket::Clear();
|
||||
}
|
||||
}
|
||||
::memset(_has_bits_, 0, sizeof(_has_bits_));
|
||||
}
|
||||
@ -3212,6 +3380,20 @@ bool Packet::MergePartialFromCodedStream(
|
||||
} else {
|
||||
goto handle_uninterpreted;
|
||||
}
|
||||
if (input->ExpectTag(50)) goto parse_meta;
|
||||
break;
|
||||
}
|
||||
|
||||
// optional .mozilla.layers.layerscope.MetaPacket meta = 6;
|
||||
case 6: {
|
||||
if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
|
||||
::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
|
||||
parse_meta:
|
||||
DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
|
||||
input, mutable_meta()));
|
||||
} else {
|
||||
goto handle_uninterpreted;
|
||||
}
|
||||
if (input->ExpectAtEnd()) return true;
|
||||
break;
|
||||
}
|
||||
@ -3263,6 +3445,12 @@ void Packet::SerializeWithCachedSizes(
|
||||
5, this->layers(), output);
|
||||
}
|
||||
|
||||
// optional .mozilla.layers.layerscope.MetaPacket meta = 6;
|
||||
if (has_meta()) {
|
||||
::google::protobuf::internal::WireFormatLite::WriteMessage(
|
||||
6, this->meta(), output);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int Packet::ByteSize() const {
|
||||
@ -3303,6 +3491,13 @@ int Packet::ByteSize() const {
|
||||
this->layers());
|
||||
}
|
||||
|
||||
// optional .mozilla.layers.layerscope.MetaPacket meta = 6;
|
||||
if (has_meta()) {
|
||||
total_size += 1 +
|
||||
::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
|
||||
this->meta());
|
||||
}
|
||||
|
||||
}
|
||||
GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
|
||||
_cached_size_ = total_size;
|
||||
@ -3333,6 +3528,9 @@ void Packet::MergeFrom(const Packet& from) {
|
||||
if (from.has_layers()) {
|
||||
mutable_layers()->::mozilla::layers::layerscope::LayersPacket::MergeFrom(from.layers());
|
||||
}
|
||||
if (from.has_meta()) {
|
||||
mutable_meta()->::mozilla::layers::layerscope::MetaPacket::MergeFrom(from.meta());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3364,6 +3562,7 @@ void Packet::Swap(Packet* other) {
|
||||
std::swap(color_, other->color_);
|
||||
std::swap(texture_, other->texture_);
|
||||
std::swap(layers_, other->layers_);
|
||||
std::swap(meta_, other->meta_);
|
||||
std::swap(_has_bits_[0], other->_has_bits_[0]);
|
||||
std::swap(_cached_size_, other->_cached_size_);
|
||||
}
|
||||
|
@ -43,6 +43,7 @@ class LayersPacket_Layer_Rect;
|
||||
class LayersPacket_Layer_Region;
|
||||
class LayersPacket_Layer_Matrix;
|
||||
class LayersPacket_Layer_Shadow;
|
||||
class MetaPacket;
|
||||
class Packet;
|
||||
|
||||
enum LayersPacket_Layer_LayerType {
|
||||
@ -89,11 +90,12 @@ enum Packet_DataType {
|
||||
Packet_DataType_FRAMEEND = 2,
|
||||
Packet_DataType_COLOR = 3,
|
||||
Packet_DataType_TEXTURE = 4,
|
||||
Packet_DataType_LAYERS = 5
|
||||
Packet_DataType_LAYERS = 5,
|
||||
Packet_DataType_META = 6
|
||||
};
|
||||
bool Packet_DataType_IsValid(int value);
|
||||
const Packet_DataType Packet_DataType_DataType_MIN = Packet_DataType_FRAMESTART;
|
||||
const Packet_DataType Packet_DataType_DataType_MAX = Packet_DataType_LAYERS;
|
||||
const Packet_DataType Packet_DataType_DataType_MAX = Packet_DataType_META;
|
||||
const int Packet_DataType_DataType_ARRAYSIZE = Packet_DataType_DataType_MAX + 1;
|
||||
|
||||
// ===================================================================
|
||||
@ -1229,6 +1231,75 @@ class LayersPacket : public ::google::protobuf::MessageLite {
|
||||
};
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
class MetaPacket : public ::google::protobuf::MessageLite {
|
||||
public:
|
||||
MetaPacket();
|
||||
virtual ~MetaPacket();
|
||||
|
||||
MetaPacket(const MetaPacket& from);
|
||||
|
||||
inline MetaPacket& operator=(const MetaPacket& from) {
|
||||
CopyFrom(from);
|
||||
return *this;
|
||||
}
|
||||
|
||||
static const MetaPacket& default_instance();
|
||||
|
||||
void Swap(MetaPacket* other);
|
||||
|
||||
// implements Message ----------------------------------------------
|
||||
|
||||
MetaPacket* New() const;
|
||||
void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
|
||||
void CopyFrom(const MetaPacket& from);
|
||||
void MergeFrom(const MetaPacket& from);
|
||||
void Clear();
|
||||
bool IsInitialized() const;
|
||||
|
||||
int ByteSize() const;
|
||||
bool MergePartialFromCodedStream(
|
||||
::google::protobuf::io::CodedInputStream* input);
|
||||
void SerializeWithCachedSizes(
|
||||
::google::protobuf::io::CodedOutputStream* output) const;
|
||||
int GetCachedSize() const { return _cached_size_; }
|
||||
private:
|
||||
void SharedCtor();
|
||||
void SharedDtor();
|
||||
void SetCachedSize(int size) const;
|
||||
public:
|
||||
|
||||
::std::string GetTypeName() const;
|
||||
|
||||
// nested types ----------------------------------------------------
|
||||
|
||||
// accessors -------------------------------------------------------
|
||||
|
||||
// optional bool composedByHwc = 1;
|
||||
inline bool has_composedbyhwc() const;
|
||||
inline void clear_composedbyhwc();
|
||||
static const int kComposedByHwcFieldNumber = 1;
|
||||
inline bool composedbyhwc() const;
|
||||
inline void set_composedbyhwc(bool value);
|
||||
|
||||
// @@protoc_insertion_point(class_scope:mozilla.layers.layerscope.MetaPacket)
|
||||
private:
|
||||
inline void set_has_composedbyhwc();
|
||||
inline void clear_has_composedbyhwc();
|
||||
|
||||
bool composedbyhwc_;
|
||||
|
||||
mutable int _cached_size_;
|
||||
::google::protobuf::uint32 _has_bits_[(1 + 31) / 32];
|
||||
|
||||
friend void protobuf_AddDesc_LayerScopePacket_2eproto();
|
||||
friend void protobuf_AssignDesc_LayerScopePacket_2eproto();
|
||||
friend void protobuf_ShutdownFile_LayerScopePacket_2eproto();
|
||||
|
||||
void InitAsDefaultInstance();
|
||||
static MetaPacket* default_instance_;
|
||||
};
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
class Packet : public ::google::protobuf::MessageLite {
|
||||
public:
|
||||
Packet();
|
||||
@ -1276,6 +1347,7 @@ class Packet : public ::google::protobuf::MessageLite {
|
||||
static const DataType COLOR = Packet_DataType_COLOR;
|
||||
static const DataType TEXTURE = Packet_DataType_TEXTURE;
|
||||
static const DataType LAYERS = Packet_DataType_LAYERS;
|
||||
static const DataType META = Packet_DataType_META;
|
||||
static inline bool DataType_IsValid(int value) {
|
||||
return Packet_DataType_IsValid(value);
|
||||
}
|
||||
@ -1327,6 +1399,14 @@ class Packet : public ::google::protobuf::MessageLite {
|
||||
inline ::mozilla::layers::layerscope::LayersPacket* mutable_layers();
|
||||
inline ::mozilla::layers::layerscope::LayersPacket* release_layers();
|
||||
|
||||
// optional .mozilla.layers.layerscope.MetaPacket meta = 6;
|
||||
inline bool has_meta() const;
|
||||
inline void clear_meta();
|
||||
static const int kMetaFieldNumber = 6;
|
||||
inline const ::mozilla::layers::layerscope::MetaPacket& meta() const;
|
||||
inline ::mozilla::layers::layerscope::MetaPacket* mutable_meta();
|
||||
inline ::mozilla::layers::layerscope::MetaPacket* release_meta();
|
||||
|
||||
// @@protoc_insertion_point(class_scope:mozilla.layers.layerscope.Packet)
|
||||
private:
|
||||
inline void set_has_type();
|
||||
@ -1339,15 +1419,18 @@ class Packet : public ::google::protobuf::MessageLite {
|
||||
inline void clear_has_texture();
|
||||
inline void set_has_layers();
|
||||
inline void clear_has_layers();
|
||||
inline void set_has_meta();
|
||||
inline void clear_has_meta();
|
||||
|
||||
::mozilla::layers::layerscope::FramePacket* frame_;
|
||||
::mozilla::layers::layerscope::ColorPacket* color_;
|
||||
::mozilla::layers::layerscope::TexturePacket* texture_;
|
||||
::mozilla::layers::layerscope::LayersPacket* layers_;
|
||||
::mozilla::layers::layerscope::MetaPacket* meta_;
|
||||
int type_;
|
||||
|
||||
mutable int _cached_size_;
|
||||
::google::protobuf::uint32 _has_bits_[(5 + 31) / 32];
|
||||
::google::protobuf::uint32 _has_bits_[(6 + 31) / 32];
|
||||
|
||||
friend void protobuf_AddDesc_LayerScopePacket_2eproto();
|
||||
friend void protobuf_AssignDesc_LayerScopePacket_2eproto();
|
||||
@ -2524,6 +2607,32 @@ LayersPacket::mutable_layer() {
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
// MetaPacket
|
||||
|
||||
// optional bool composedByHwc = 1;
|
||||
inline bool MetaPacket::has_composedbyhwc() const {
|
||||
return (_has_bits_[0] & 0x00000001u) != 0;
|
||||
}
|
||||
inline void MetaPacket::set_has_composedbyhwc() {
|
||||
_has_bits_[0] |= 0x00000001u;
|
||||
}
|
||||
inline void MetaPacket::clear_has_composedbyhwc() {
|
||||
_has_bits_[0] &= ~0x00000001u;
|
||||
}
|
||||
inline void MetaPacket::clear_composedbyhwc() {
|
||||
composedbyhwc_ = false;
|
||||
clear_has_composedbyhwc();
|
||||
}
|
||||
inline bool MetaPacket::composedbyhwc() const {
|
||||
return composedbyhwc_;
|
||||
}
|
||||
inline void MetaPacket::set_composedbyhwc(bool value) {
|
||||
set_has_composedbyhwc();
|
||||
composedbyhwc_ = value;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
// Packet
|
||||
|
||||
// required .mozilla.layers.layerscope.Packet.DataType type = 1;
|
||||
@ -2665,6 +2774,35 @@ inline ::mozilla::layers::layerscope::LayersPacket* Packet::release_layers() {
|
||||
return temp;
|
||||
}
|
||||
|
||||
// optional .mozilla.layers.layerscope.MetaPacket meta = 6;
|
||||
inline bool Packet::has_meta() const {
|
||||
return (_has_bits_[0] & 0x00000020u) != 0;
|
||||
}
|
||||
inline void Packet::set_has_meta() {
|
||||
_has_bits_[0] |= 0x00000020u;
|
||||
}
|
||||
inline void Packet::clear_has_meta() {
|
||||
_has_bits_[0] &= ~0x00000020u;
|
||||
}
|
||||
inline void Packet::clear_meta() {
|
||||
if (meta_ != NULL) meta_->::mozilla::layers::layerscope::MetaPacket::Clear();
|
||||
clear_has_meta();
|
||||
}
|
||||
inline const ::mozilla::layers::layerscope::MetaPacket& Packet::meta() const {
|
||||
return meta_ != NULL ? *meta_ : *default_instance_->meta_;
|
||||
}
|
||||
inline ::mozilla::layers::layerscope::MetaPacket* Packet::mutable_meta() {
|
||||
set_has_meta();
|
||||
if (meta_ == NULL) meta_ = new ::mozilla::layers::layerscope::MetaPacket;
|
||||
return meta_;
|
||||
}
|
||||
inline ::mozilla::layers::layerscope::MetaPacket* Packet::release_meta() {
|
||||
clear_has_meta();
|
||||
::mozilla::layers::layerscope::MetaPacket* temp = meta_;
|
||||
meta_ = NULL;
|
||||
return temp;
|
||||
}
|
||||
|
||||
|
||||
// @@protoc_insertion_point(namespace_scope)
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
|
||||
option optimize_for = LITE_RUNTIME;
|
||||
|
||||
package mozilla.layers.layerscope;
|
||||
@ -108,6 +110,10 @@ message LayersPacket {
|
||||
repeated Layer layer = 1;
|
||||
}
|
||||
|
||||
message MetaPacket {
|
||||
optional bool composedByHwc = 1;
|
||||
}
|
||||
|
||||
// We only need to use this Packet.
|
||||
// Other packet definitions are just type defines
|
||||
message Packet {
|
||||
@ -117,6 +123,7 @@ message Packet {
|
||||
COLOR = 3;
|
||||
TEXTURE = 4;
|
||||
LAYERS = 5;
|
||||
META = 6;
|
||||
}
|
||||
required DataType type = 1;
|
||||
|
||||
@ -124,4 +131,5 @@ message Packet {
|
||||
optional ColorPacket color = 3;
|
||||
optional TexturePacket texture = 4;
|
||||
optional LayersPacket layers = 5;
|
||||
optional MetaPacket meta = 6;
|
||||
}
|
||||
|
@ -375,18 +375,19 @@ nsDeviceContext::SetDPI()
|
||||
nsresult
|
||||
nsDeviceContext::Init(nsIWidget *aWidget)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
if (mScreenManager && mWidget == aWidget)
|
||||
return NS_OK;
|
||||
return rv;
|
||||
|
||||
mWidget = aWidget;
|
||||
SetDPI();
|
||||
|
||||
if (mScreenManager)
|
||||
return NS_OK;
|
||||
return rv;
|
||||
|
||||
mScreenManager = do_GetService("@mozilla.org/gfx/screenmanager;1");
|
||||
mScreenManager = do_GetService("@mozilla.org/gfx/screenmanager;1", &rv);
|
||||
|
||||
return NS_OK;
|
||||
return rv;
|
||||
}
|
||||
|
||||
already_AddRefed<gfxContext>
|
||||
@ -422,7 +423,7 @@ nsDeviceContext::CreateRenderingContext()
|
||||
nsresult
|
||||
nsDeviceContext::GetDepth(uint32_t& aDepth)
|
||||
{
|
||||
if (mDepth == 0) {
|
||||
if (mDepth == 0 && mScreenManager) {
|
||||
nsCOMPtr<nsIScreen> primaryScreen;
|
||||
mScreenManager->GetPrimaryScreen(getter_AddRefs(primaryScreen));
|
||||
primaryScreen->GetColorDepth(reinterpret_cast<int32_t *>(&mDepth));
|
||||
@ -644,11 +645,15 @@ nsDeviceContext::ComputeFullAreaUsingScreen(nsRect* outRect)
|
||||
void
|
||||
nsDeviceContext::FindScreen(nsIScreen** outScreen)
|
||||
{
|
||||
if (mWidget && mWidget->GetOwningTabChild()) {
|
||||
if (!mWidget || !mScreenManager) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mWidget->GetOwningTabChild()) {
|
||||
mScreenManager->ScreenForNativeWidget((void *)mWidget->GetOwningTabChild(),
|
||||
outScreen);
|
||||
}
|
||||
else if (mWidget && mWidget->GetNativeData(NS_NATIVE_WINDOW)) {
|
||||
else if (mWidget->GetNativeData(NS_NATIVE_WINDOW)) {
|
||||
mScreenManager->ScreenForNativeWidget(mWidget->GetNativeData(NS_NATIVE_WINDOW),
|
||||
outScreen);
|
||||
}
|
||||
|
@ -327,6 +327,7 @@ NS_IMPL_ISUPPORTS(GPUAdapterReporter, nsIMemoryReporter)
|
||||
|
||||
gfxWindowsPlatform::gfxWindowsPlatform()
|
||||
: mD3D11DeviceInitialized(false)
|
||||
, mIsWARP(false)
|
||||
{
|
||||
mUseClearTypeForDownloadableFonts = UNINITIALIZED_VALUE;
|
||||
mUseClearTypeAlways = UNINITIALIZED_VALUE;
|
||||
@ -1787,6 +1788,7 @@ gfxWindowsPlatform::InitD3D11Devices()
|
||||
MOZ_CRASH();
|
||||
}
|
||||
|
||||
mIsWARP = true;
|
||||
reporterWARP.SetSuccessful();
|
||||
}
|
||||
|
||||
|
@ -250,6 +250,8 @@ public:
|
||||
|
||||
static bool IsOptimus();
|
||||
|
||||
bool IsWARP() { return mIsWARP; }
|
||||
|
||||
protected:
|
||||
RenderMode mRenderMode;
|
||||
|
||||
@ -279,6 +281,7 @@ private:
|
||||
mozilla::RefPtr<ID3D11Device> mD3D11ContentDevice;
|
||||
bool mD3D11DeviceInitialized;
|
||||
mozilla::RefPtr<mozilla::layers::ReadbackManagerD3D11> mD3D11ReadbackManager;
|
||||
bool mIsWARP;
|
||||
|
||||
virtual void GetPlatformCMSOutputProfile(void* &mem, size_t &size);
|
||||
};
|
||||
|
@ -66,7 +66,7 @@ LOCAL_INCLUDES += [
|
||||
# Because VectorImage.cpp includes nsSVGUtils.h and nsSVGEffects.h
|
||||
'/layout/svg',
|
||||
# For URI-related functionality
|
||||
'/netwerk/base/src',
|
||||
'/netwerk/base',
|
||||
]
|
||||
|
||||
# Because imgFrame.cpp includes "cairo.h"
|
||||
|
@ -20,8 +20,15 @@
|
||||
#include "base/string16.h"
|
||||
|
||||
#if defined(COMPILER_MSVC) || (defined(ANDROID) && defined(_STLP_STD_NAME))
|
||||
#ifdef COMPILER_MSVC
|
||||
#pragma push_macro("_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS")
|
||||
#define _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS
|
||||
#endif
|
||||
#include <hash_map>
|
||||
#include <hash_set>
|
||||
#ifdef COMPILER_MSVC
|
||||
#pragma pop_macro("_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS")
|
||||
#endif
|
||||
namespace base {
|
||||
#ifdef ANDROID
|
||||
using _STLP_STD_NAME::hash_map;
|
||||
|
@ -197,7 +197,8 @@ class ScopedRunnableMethodFactory : public RevocableStore {
|
||||
virtual void Run() { DispatchToMethod(obj_, meth_, params_); }
|
||||
|
||||
private:
|
||||
T* obj_;
|
||||
T* MOZ_UNSAFE_REF("The validity of this pointer must be enforced by "
|
||||
"external factors.") obj_;
|
||||
Method meth_;
|
||||
Params params_;
|
||||
|
||||
@ -225,7 +226,8 @@ class DeleteTask : public CancelableTask {
|
||||
obj_ = NULL;
|
||||
}
|
||||
private:
|
||||
T* obj_;
|
||||
T* MOZ_UNSAFE_REF("The validity of this pointer must be enforced by "
|
||||
"external factors.") obj_;
|
||||
};
|
||||
|
||||
// Task to Release() an object
|
||||
@ -242,7 +244,8 @@ class ReleaseTask : public CancelableTask {
|
||||
obj_ = NULL;
|
||||
}
|
||||
private:
|
||||
T* obj_;
|
||||
T* MOZ_UNSAFE_REF("The validity of this pointer must be enforced by "
|
||||
"external factors.") obj_;
|
||||
};
|
||||
|
||||
// RunnableMethodTraits --------------------------------------------------------
|
||||
@ -319,7 +322,9 @@ class RunnableMethod : public CancelableTask,
|
||||
}
|
||||
}
|
||||
|
||||
T* obj_;
|
||||
// This is owning because of the RetainCallee and ReleaseCallee calls in the
|
||||
// constructor and destructor.
|
||||
T* MOZ_OWNING_REF obj_;
|
||||
Method meth_;
|
||||
Params params_;
|
||||
};
|
||||
@ -513,7 +518,8 @@ class CallbackStorage {
|
||||
}
|
||||
|
||||
protected:
|
||||
T* obj_;
|
||||
T* MOZ_UNSAFE_REF("The validity of this pointer must be enforced by "
|
||||
"external factors.") obj_;
|
||||
Method meth_;
|
||||
};
|
||||
|
||||
|
@ -71,7 +71,7 @@ TestDataStructuresParent::DeallocPTestDataStructuresSubParent(PTestDataStructure
|
||||
}
|
||||
|
||||
bool TestDataStructuresParent::RecvTest1(
|
||||
const InfallibleTArray<int>& ia,
|
||||
InfallibleTArray<int>&& ia,
|
||||
InfallibleTArray<int>* oa)
|
||||
{
|
||||
test_assert(5 == ia.Length(), "wrong length");
|
||||
@ -84,7 +84,7 @@ bool TestDataStructuresParent::RecvTest1(
|
||||
}
|
||||
|
||||
bool TestDataStructuresParent::RecvTest2(
|
||||
const InfallibleTArray<PTestDataStructuresSubParent*>& i1,
|
||||
InfallibleTArray<PTestDataStructuresSubParent*>&& i1,
|
||||
InfallibleTArray<PTestDataStructuresSubParent*>* o1)
|
||||
{
|
||||
test_assert(nactors == i1.Length(), "wrong #actors");
|
||||
@ -110,7 +110,7 @@ bool TestDataStructuresParent::RecvTest3(
|
||||
}
|
||||
|
||||
bool TestDataStructuresParent::RecvTest4(
|
||||
const InfallibleTArray<IntDouble>& i1,
|
||||
InfallibleTArray<IntDouble>&& i1,
|
||||
InfallibleTArray<IntDouble>* o1)
|
||||
{
|
||||
test_assert(4 == i1.Length(), "wrong length");
|
||||
@ -171,7 +171,7 @@ TestDataStructuresParent::RecvTest7_0(const ActorWrapper& i1,
|
||||
}
|
||||
|
||||
bool TestDataStructuresParent::RecvTest6(
|
||||
const InfallibleTArray<IntDoubleArrays>& i1,
|
||||
InfallibleTArray<IntDoubleArrays>&& i1,
|
||||
InfallibleTArray<IntDoubleArrays>* o1)
|
||||
{
|
||||
test_assert(3 == i1.Length(), "wrong length");
|
||||
@ -224,7 +224,7 @@ bool TestDataStructuresParent::RecvTest7(
|
||||
}
|
||||
|
||||
bool TestDataStructuresParent::RecvTest8(
|
||||
const InfallibleTArray<Actors>& i1,
|
||||
InfallibleTArray<Actors>&& i1,
|
||||
InfallibleTArray<Actors>* o1)
|
||||
{
|
||||
test_assert(3 == i1.Length(), "wrong length");
|
||||
@ -276,7 +276,7 @@ bool TestDataStructuresParent::RecvTest9(
|
||||
}
|
||||
|
||||
bool TestDataStructuresParent::RecvTest10(
|
||||
const InfallibleTArray<Unions>& i1,
|
||||
InfallibleTArray<Unions>&& i1,
|
||||
InfallibleTArray<Unions>* o1)
|
||||
{
|
||||
test_assert(42 == i1[0].get_int(), "wrong value");
|
||||
@ -438,14 +438,14 @@ bool TestDataStructuresParent::RecvTest16(
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TestDataStructuresParent::RecvTest17(const InfallibleTArray<Op>& sa)
|
||||
bool TestDataStructuresParent::RecvTest17(InfallibleTArray<Op>&& sa)
|
||||
{
|
||||
test_assert(sa.Length() == 1 && Op::TSetAttrs == sa[0].type(),
|
||||
"wrong value");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TestDataStructuresParent::RecvTest18(const RegionArray& ra)
|
||||
bool TestDataStructuresParent::RecvTest18(RegionArray&& ra)
|
||||
{
|
||||
for (RegionArray::index_type i = 0; i < ra.Length(); ++i) {
|
||||
nsIntRegionRectIterator it(ra[i]);
|
||||
|
@ -58,11 +58,11 @@ protected:
|
||||
virtual bool DeallocPTestDataStructuresSubParent(PTestDataStructuresSubParent* actor) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvTest1(
|
||||
const InfallibleTArray<int>& i1,
|
||||
InfallibleTArray<int>&& i1,
|
||||
InfallibleTArray<int>* o1) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvTest2(
|
||||
const InfallibleTArray<PTestDataStructuresSubParent*>& i1,
|
||||
InfallibleTArray<PTestDataStructuresSubParent*>&& i1,
|
||||
InfallibleTArray<PTestDataStructuresSubParent*>* o1) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvTest3(
|
||||
@ -72,7 +72,7 @@ protected:
|
||||
IntDouble* o2) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvTest4(
|
||||
const InfallibleTArray<IntDouble>& i1,
|
||||
InfallibleTArray<IntDouble>&& i1,
|
||||
InfallibleTArray<IntDouble>* o1) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvTest5(
|
||||
@ -84,7 +84,7 @@ protected:
|
||||
IntDoubleArrays* o3) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvTest6(
|
||||
const InfallibleTArray<IntDoubleArrays>& i1,
|
||||
InfallibleTArray<IntDoubleArrays>&& i1,
|
||||
InfallibleTArray<IntDoubleArrays>* o1) MOZ_OVERRIDE;
|
||||
|
||||
|
||||
@ -100,7 +100,7 @@ protected:
|
||||
Actors* o3) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvTest8(
|
||||
const InfallibleTArray<Actors>& i1,
|
||||
InfallibleTArray<Actors>&& i1,
|
||||
InfallibleTArray<Actors>* o1) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvTest9(
|
||||
@ -114,7 +114,7 @@ protected:
|
||||
Unions* o4) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvTest10(
|
||||
const InfallibleTArray<Unions>& i1,
|
||||
InfallibleTArray<Unions>&& i1,
|
||||
InfallibleTArray<Unions>* o1) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvTest11(
|
||||
@ -149,9 +149,9 @@ protected:
|
||||
const WithUnions& i,
|
||||
WithUnions* o) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvTest17(const InfallibleTArray<Op>& sa) MOZ_OVERRIDE;
|
||||
virtual bool RecvTest17(InfallibleTArray<Op>&& sa) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvTest18(const InfallibleTArray<nsIntRegion>& ra) MOZ_OVERRIDE;
|
||||
virtual bool RecvTest18(InfallibleTArray<nsIntRegion>&& ra) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvDummy(const ShmemUnion& su, ShmemUnion* rsu) MOZ_OVERRIDE
|
||||
{
|
||||
|
@ -51,7 +51,7 @@ TestShmemParent::Main()
|
||||
|
||||
|
||||
bool
|
||||
TestShmemParent::RecvTake(Shmem& mem, Shmem& unsafe,
|
||||
TestShmemParent::RecvTake(Shmem&& mem, Shmem&& unsafe,
|
||||
const size_t& expectedSize)
|
||||
{
|
||||
if (mem.Size<char>() != expectedSize)
|
||||
@ -80,7 +80,7 @@ TestShmemParent::RecvTake(Shmem& mem, Shmem& unsafe,
|
||||
// Child
|
||||
|
||||
bool
|
||||
TestShmemChild::RecvGive(Shmem& mem, Shmem& unsafe, const size_t& expectedSize)
|
||||
TestShmemChild::RecvGive(Shmem&& mem, Shmem&& unsafe, const size_t& expectedSize)
|
||||
{
|
||||
if (mem.Size<char>() != expectedSize)
|
||||
fail("expected shmem size %lu, but it has size %lu",
|
||||
|
@ -24,8 +24,8 @@ public:
|
||||
|
||||
protected:
|
||||
virtual bool RecvTake(
|
||||
Shmem& mem,
|
||||
Shmem& unsafe,
|
||||
Shmem&& mem,
|
||||
Shmem&& unsafe,
|
||||
const size_t& expectedSize) MOZ_OVERRIDE;
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE
|
||||
@ -47,8 +47,8 @@ public:
|
||||
|
||||
protected:
|
||||
virtual bool RecvGive(
|
||||
Shmem& mem,
|
||||
Shmem& unsafe,
|
||||
Shmem&& mem,
|
||||
Shmem&& unsafe,
|
||||
const size_t& expectedSize) MOZ_OVERRIDE;
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE
|
||||
|
@ -56,7 +56,7 @@ TestSysVShmemParent::Main()
|
||||
|
||||
|
||||
bool
|
||||
TestSysVShmemParent::RecvTake(Shmem& mem, Shmem& unsafe,
|
||||
TestSysVShmemParent::RecvTake(Shmem&& mem, Shmem&& unsafe,
|
||||
const size_t& expectedSize)
|
||||
{
|
||||
if (mem.Size<char>() != expectedSize)
|
||||
@ -85,7 +85,7 @@ TestSysVShmemParent::RecvTake(Shmem& mem, Shmem& unsafe,
|
||||
// Child
|
||||
|
||||
bool
|
||||
TestSysVShmemChild::RecvGive(Shmem& mem, Shmem& unsafe, const size_t& expectedSize)
|
||||
TestSysVShmemChild::RecvGive(Shmem&& mem, Shmem&& unsafe, const size_t& expectedSize)
|
||||
{
|
||||
if (mem.Size<char>() != expectedSize)
|
||||
fail("expected shmem size %lu, but it has size %lu",
|
||||
|
@ -24,8 +24,8 @@ public:
|
||||
|
||||
protected:
|
||||
virtual bool RecvTake(
|
||||
Shmem& mem,
|
||||
Shmem& unsafe,
|
||||
Shmem&& mem,
|
||||
Shmem&& unsafe,
|
||||
const size_t& expectedSize) MOZ_OVERRIDE;
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE
|
||||
@ -47,8 +47,8 @@ public:
|
||||
|
||||
protected:
|
||||
virtual bool RecvGive(
|
||||
Shmem& mem,
|
||||
Shmem& unsafe,
|
||||
Shmem&& mem,
|
||||
Shmem&& unsafe,
|
||||
const size_t& expectedSize) MOZ_OVERRIDE;
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user