Merge autoland to mozilla-central. a=merge

This commit is contained in:
Ciure Andrei 2019-11-25 06:22:39 +02:00
Родитель a05312fec5 2989d5b788
Коммит 96141919a9
28 изменённых файлов: 428 добавлений и 80 удалений

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

@ -1212,6 +1212,12 @@ var gSync = {
if (confirm && !(await this._confirmDisconnect(disconnectAccount))) {
return false;
}
// Record telemetry.
await fxAccounts.telemetry.recordDisconnection(
disconnectAccount ? null : "sync",
"ui"
);
await Weave.Service.promiseInitialized;
await Weave.Service.startOver();
if (disconnectAccount) {

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

@ -81,6 +81,7 @@ skip-if = fission
skip-if = (verify && debug && (os == 'win'))
[browser_imageCacheIsolation.js]
[browser_sharedworker.js]
skip-if = fission #Bug 1582318
[browser_httpauth.js]
[browser_clientAuth.js]
skip-if = verify

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

@ -302,7 +302,14 @@ var gSyncPane = {
if (!isAlreadySyncing && event.detail.button == "accept") {
// We weren't syncing but the user has accepted the dialog - so we
// want to start!
Weave.Service.configure();
fxAccounts.telemetry
.recordConnection(["sync"], "ui")
.then(() => {
return Weave.Service.configure();
})
.catch(err => {
console.error("Failed to enable sync", err);
});
}
}
);

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

@ -80,16 +80,18 @@ class CompatibilityView {
);
}
_isVisible() {
_isAvailable() {
return (
this.inspector &&
this.inspector.sidebar &&
this.inspector.sidebar.getCurrentTabID() === "compatibilityview"
this.inspector.sidebar.getCurrentTabID() === "compatibilityview" &&
this.inspector.selection &&
this.inspector.selection.isConnected()
);
}
_onNewNode() {
if (!this._isVisible()) {
if (!this._isAvailable()) {
return;
}

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

@ -5,19 +5,35 @@
"use strict";
const {
COMPATIBILITY_UPDATE_SELECTED_NODE,
COMPATIBILITY_UPDATE_SELECTED_NODE_START,
COMPATIBILITY_UPDATE_SELECTED_NODE_SUCCESS,
COMPATIBILITY_UPDATE_SELECTED_NODE_FAILURE,
COMPATIBILITY_UPDATE_SELECTED_NODE_COMPLETE,
COMPATIBILITY_UPDATE_TARGET_BROWSERS,
} = require("./index");
function updateSelectedNode(nodeFront) {
return async ({ dispatch }) => {
const pageStyle = nodeFront.inspectorFront.pageStyle;
const styles = await pageStyle.getApplied(nodeFront, { skipPseudo: false });
const declarationBlocks = styles
.map(({ rule }) => rule.declarations.filter(d => !d.commentOffsets))
.filter(declarations => declarations.length);
dispatch({ type: COMPATIBILITY_UPDATE_SELECTED_NODE_START });
dispatch({ type: COMPATIBILITY_UPDATE_SELECTED_NODE, declarationBlocks });
try {
const pageStyle = nodeFront.inspectorFront.pageStyle;
const styles = await pageStyle.getApplied(nodeFront, {
skipPseudo: false,
});
const declarationBlocks = styles
.map(({ rule }) => rule.declarations.filter(d => !d.commentOffsets))
.filter(declarations => declarations.length);
dispatch({
type: COMPATIBILITY_UPDATE_SELECTED_NODE_SUCCESS,
declarationBlocks,
});
} catch (error) {
dispatch({ type: COMPATIBILITY_UPDATE_SELECTED_NODE_FAILURE, error });
}
dispatch({ type: COMPATIBILITY_UPDATE_SELECTED_NODE_COMPLETE });
};
}

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

@ -9,7 +9,10 @@ const { createEnum } = require("devtools/client/shared/enum");
createEnum(
[
// Updates the selected node.
"COMPATIBILITY_UPDATE_SELECTED_NODE",
"COMPATIBILITY_UPDATE_SELECTED_NODE_START",
"COMPATIBILITY_UPDATE_SELECTED_NODE_SUCCESS",
"COMPATIBILITY_UPDATE_SELECTED_NODE_FAILURE",
"COMPATIBILITY_UPDATE_SELECTED_NODE_COMPLETE",
// Updates the target browsers.
"COMPATIBILITY_UPDATE_TARGET_BROWSERS",

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

@ -11,7 +11,8 @@ loader.lazyGetter(this, "mdnCompatibility", () => {
});
const {
COMPATIBILITY_UPDATE_SELECTED_NODE,
COMPATIBILITY_UPDATE_SELECTED_NODE_SUCCESS,
COMPATIBILITY_UPDATE_SELECTED_NODE_FAILURE,
COMPATIBILITY_UPDATE_TARGET_BROWSERS,
} = require("../actions/index");
@ -22,9 +23,16 @@ const INITIAL_STATE = {
};
const reducers = {
[COMPATIBILITY_UPDATE_SELECTED_NODE](state, data) {
[COMPATIBILITY_UPDATE_SELECTED_NODE_SUCCESS](state, data) {
return updateSelectedNodeIssues(state, data);
},
[COMPATIBILITY_UPDATE_SELECTED_NODE_FAILURE](state, { error }) {
console.error(
`[COMPATIBILITY_UPDATE_SELECTED_NODE_FAILURE] ${error.message}`
);
console.error(error.stack);
return state;
},
[COMPATIBILITY_UPDATE_TARGET_BROWSERS](state, data) {
return updateSelectedNodeIssues(state, data);
},

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

@ -12,6 +12,7 @@ support-files =
[browser_compatibility_css-property_issue.js]
[browser_compatibility_event_new-node.js]
[browser_compatibility_event_new-node_without-connection.js]
[browser_compatibility_event_rule-change.js]
[browser_compatibility_preference.js]
[browser_compatibility_unsupported-browsers_all.js]

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

@ -0,0 +1,32 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test whether no errors occur when reloading the browsing page.
const {
COMPATIBILITY_UPDATE_SELECTED_NODE_FAILURE,
} = require("devtools/client/inspector/compatibility/actions/index");
add_task(async function() {
const tab = await addTab("data:text/html;charset=utf-8,test");
const { inspector } = await openCompatibilityView();
let isFailureActionFired = false;
waitForDispatch(
inspector.store,
COMPATIBILITY_UPDATE_SELECTED_NODE_FAILURE
).then(() => {
isFailureActionFired = true;
});
info("Reload the browsing page");
const onReloaded = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
const onUpdateAction = waitForUpdateSelectedNodeAction(inspector.store);
gBrowser.reloadTab(tab);
await Promise.all([onReloaded, onUpdateAction]);
info("Check whether the failure action will be fired or not");
ok(!isFailureActionFired, "No error occurred");
});

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

@ -11,6 +11,10 @@ Services.scriptloader.loadSubScript(
this
);
const {
COMPATIBILITY_UPDATE_SELECTED_NODE_COMPLETE,
} = require("devtools/client/inspector/compatibility/actions/index");
const {
toCamelCase,
} = require("devtools/client/inspector/compatibility/utils/cases");
@ -20,6 +24,7 @@ async function openCompatibilityView() {
await pushPref("devtools.inspector.compatibility.enabled", true);
const { inspector } = await openInspectorSidebarTab("compatibilityview");
await waitForUpdateSelectedNodeAction(inspector.store);
const panel = inspector.panelDoc.querySelector(
"#compatibilityview-panel .inspector-tabpanel"
);
@ -66,3 +71,32 @@ async function assertIssueList(panel, expectedIssues) {
}
}
}
/**
* Return a promise which waits for COMPATIBILITY_UPDATE_SELECTED_NODE_COMPLETE action.
*
* @param {Object} store
* @return {Promise}
*/
function waitForUpdateSelectedNodeAction(store) {
return waitForDispatch(store, COMPATIBILITY_UPDATE_SELECTED_NODE_COMPLETE);
}
/**
* Return a promise which waits for given action type.
*
* @param {Object} store
* @param {Object} type
* @return {Promise}
*/
function waitForDispatch(store, type) {
return new Promise(resolve => {
store.dispatch({
type: "@@service/waitUntil",
predicate: action => action.type === type,
run: (dispatch, getState, action) => {
resolve(action);
},
});
});
}

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

@ -140,9 +140,7 @@ void BrowserBridgeParent::Destroy() {
IPCResult BrowserBridgeParent::RecvShow(const ScreenIntSize& aSize,
const bool& aParentIsActive,
const nsSizeMode& aSizeMode) {
if (!mBrowserParent->AttachLayerManager()) {
MOZ_CRASH();
}
mBrowserParent->AttachLayerManager();
Unused << mBrowserParent->SendShow(aSize, mBrowserParent->GetShowInfo(),
aParentIsActive, aSizeMode);
return IPC_OK();

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

@ -10,13 +10,18 @@
#include <d3d11.h>
#include <assert.h>
#include <map>
#include <vector>
#define EGL_EGL_PROTOTYPES 1
#define EGL_EGLEXT_PROTOTYPES 1
#define GL_GLEXT_PROTOTYPES 1
#include "EGL/egl.h"
#include "EGL/eglext.h"
#include "EGL/eglext_angle.h"
#include "GL/gl.h"
#include "GLES/gl.h"
#include "GLES/glext.h"
#include "GLES3/gl3.h"
// The OS compositor representation of a picture cache tile.
struct Tile {
@ -26,6 +31,13 @@ struct Tile {
IDCompositionVisual2 *pVisual;
};
struct CachedFrameBuffer {
int width;
int height;
GLuint fboId;
GLuint depthRboId;
};
struct Window {
// Win32 window details
HWND hWnd;
@ -50,8 +62,9 @@ struct Window {
EGLSurface fb_surface;
// The currently bound surface, valid during bind() and unbind()
EGLSurface current_surface;
IDCompositionSurface *pCurrentSurface;
EGLImage mEGLImage;
GLuint mColorRBO;
// The root of the DC visual tree. Nothing is drawn on this, but
// all child tiles are parented to here.
@ -59,10 +72,50 @@ struct Window {
IDCompositionVisualDebug *pVisualDebug;
// Maps the WR surface IDs to the DC representation of each tile.
std::map<uint64_t, Tile> tiles;
std::vector<CachedFrameBuffer> mFrameBuffers;
};
static const wchar_t *CLASS_NAME = L"WR DirectComposite";
static GLuint GetOrCreateFbo(Window *window, int aWidth, int aHeight) {
GLuint fboId = 0;
// Check if we have a cached FBO with matching dimensions
for (auto it = window->mFrameBuffers.begin(); it != window->mFrameBuffers.end(); ++it) {
if (it->width == aWidth && it->height == aHeight) {
fboId = it->fboId;
break;
}
}
// If not, create a new FBO with attached depth buffer
if (fboId == 0) {
// Create the depth buffer
GLuint depthRboId;
glGenRenderbuffers(1, &depthRboId);
glBindRenderbuffer(GL_RENDERBUFFER, depthRboId);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24,
aWidth, aHeight);
// Create the framebuffer and attach the depth buffer to it
glGenFramebuffers(1, &fboId);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboId);
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER,
GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER, depthRboId);
// Store this in the cache for future calls.
CachedFrameBuffer frame_buffer_info;
frame_buffer_info.width = aWidth;
frame_buffer_info.height = aHeight;
frame_buffer_info.fboId = fboId;
frame_buffer_info.depthRboId = depthRboId;
window->mFrameBuffers.push_back(frame_buffer_info);
}
return fboId;
}
static LRESULT CALLBACK WndProc(
HWND hwnd,
UINT message,
@ -86,6 +139,7 @@ extern "C" {
window->width = width;
window->height = height;
window->enable_compositor = enable_compositor;
window->mEGLImage = EGL_NO_IMAGE;
WNDCLASSEX wcex = { sizeof(WNDCLASSEX) };
wcex.style = CS_HREDRAW | CS_VREDRAW;
@ -284,7 +338,7 @@ extern "C" {
delete window;
}
bool com_dc_tick(Window *window) {
bool com_dc_tick(Window *) {
// Check and dispatch the windows event loop
MSG msg;
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
@ -356,7 +410,7 @@ extern "C" {
}
// Bind a DC surface to allow issuing GL commands to it
void com_dc_bind_surface(
GLuint com_dc_bind_surface(
Window *window,
uint64_t id,
int *x_offset,
@ -395,35 +449,44 @@ extern "C" {
offset.y -= dirty_y0;
assert(SUCCEEDED(hr));
pTexture->GetDesc(&desc);
// Construct an EGL off-screen surface that is bound to the DC surface
EGLint buffer_attribs[] = {
EGL_WIDTH, desc.Width,
EGL_HEIGHT, desc.Height,
EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE, EGL_TRUE,
EGL_NONE
};
window->current_surface = eglCreatePbufferFromClientBuffer(
window->EGLDisplay,
EGL_D3D_TEXTURE_ANGLE,
pTexture,
window->config,
buffer_attribs
);
assert(window->current_surface != EGL_NO_SURFACE);
// Make EGL current on the DC surface
EGLBoolean ok = eglMakeCurrent(
window->EGLDisplay,
window->current_surface,
window->current_surface,
window->EGLContext
);
assert(ok);
*x_offset = offset.x;
*y_offset = offset.y;
// Construct an EGLImage wrapper around the D3D texture for ANGLE.
const EGLAttrib attribs[] = { EGL_NONE };
window->mEGLImage = eglCreateImage(
window->EGLDisplay,
EGL_NO_CONTEXT,
EGL_D3D11_TEXTURE_ANGLE,
static_cast<EGLClientBuffer>(pTexture),
attribs
);
// Get the current FBO and RBO id, so we can restore them later
GLint currentFboId, currentRboId;
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &currentFboId);
glGetIntegerv(GL_RENDERBUFFER_BINDING, &currentRboId);
// Create a render buffer object that is backed by the EGL image.
glGenRenderbuffers(1, &window->mColorRBO);
glBindRenderbuffer(GL_RENDERBUFFER, window->mColorRBO);
glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, window->mEGLImage);
// Get or create an FBO for the specified dimensions
GLuint fboId = GetOrCreateFbo(window, desc.Width, desc.Height);
// Attach the new renderbuffer to the FBO
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboId);
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
GL_RENDERBUFFER,
window->mColorRBO);
// Restore previous FBO and RBO bindings
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, currentFboId);
glBindRenderbuffer(GL_RENDERBUFFER, currentRboId);
return fboId;
}
// Unbind a currently bound DC surface
@ -431,7 +494,11 @@ extern "C" {
HRESULT hr = window->pCurrentSurface->EndDraw();
assert(SUCCEEDED(hr));
eglDestroySurface(window->EGLDisplay, window->current_surface);
glDeleteRenderbuffers(1, &window->mColorRBO);
window->mColorRBO = 0;
eglDestroyImage(window->EGLDisplay, window->mEGLImage);
window->mEGLImage = EGL_NO_IMAGE;
}
// At the start of a transaction, remove all visuals from the tree.
@ -467,8 +534,8 @@ extern "C" {
// Place the visual - this changes frame to frame based on scroll position
// of the slice.
int offset_x = x + window->client_rect.left;
int offset_y = y + window->client_rect.top;
float offset_x = (float) (x + window->client_rect.left);
float offset_y = (float) (y + window->client_rect.top);
tile.pVisual->SetOffsetX(offset_x);
tile.pVisual->SetOffsetY(offset_y);

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

@ -50,7 +50,7 @@ extern {
dirty_y0: i32,
dirty_width: i32,
dirty_height: i32,
);
) -> u32;
fn com_dc_unbind_surface(window: *mut Window);
fn com_dc_begin_transaction(window: *mut Window);
@ -130,12 +130,12 @@ pub fn bind_surface(
dirty_y0: i32,
dirty_width: i32,
dirty_height: i32,
) -> (i32, i32) {
) -> (u32, i32, i32) {
unsafe {
let mut x_offset = 0;
let mut y_offset = 0;
com_dc_bind_surface(
let fbo_id = com_dc_bind_surface(
window,
id,
&mut x_offset,
@ -146,7 +146,7 @@ pub fn bind_surface(
dirty_height,
);
(x_offset, y_offset)
(fbo_id, x_offset, y_offset)
}
}

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

@ -65,7 +65,7 @@ impl webrender::Compositor for DirectCompositeInterface {
id: webrender::NativeSurfaceId,
dirty_rect: DeviceIntRect,
) -> webrender::NativeSurfaceInfo {
let (x, y) = compositor::bind_surface(
let (fbo_id, x, y) = compositor::bind_surface(
self.window,
id.0,
dirty_rect.origin.x,
@ -76,7 +76,7 @@ impl webrender::Compositor for DirectCompositeInterface {
webrender::NativeSurfaceInfo {
origin: DeviceIntPoint::new(x, y),
fbo_id: 0,
fbo_id,
}
}

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

@ -116,7 +116,13 @@ class BinASTSourceMetadata {
public:
BinASTSourceMetadata() = delete;
explicit BinASTSourceMetadata(Type type) : type_(type) {}
#ifdef JS_BUILD_BINAST
~BinASTSourceMetadata();
#else
// If JS_BUILD_BINAST isn't defined, BinASTRuntimeSupport.cpp isn't built,
// but still the destructor is referred from ScriptSource::BinAST.
~BinASTSourceMetadata() {}
#endif // JS_BUILD_BINAST
Type type() const { return type_; }

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

@ -10981,7 +10981,7 @@ int main(int argc, char** argv, char** envp) {
"Format of BinAST file (multipart/context)") ||
#else
!op.addMultiStringOption('B', "binast", "", "No-op") ||
!op.addStringOption('\0', "binast-format", "No-op") ||
!op.addStringOption('\0', "binast-format", "[format]", "No-op") ||
#endif // JS_BUILD_BINAST
!op.addMultiStringOption('e', "execute", "CODE", "Inline code to run") ||
!op.addBoolOption('i', "shell", "Enter prompt after running code") ||

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

@ -4151,6 +4151,12 @@
value: false
mirror: always
# Whether we allow advanced layers with fission
- name: layers.advanced.fission.enabled
type: bool
value: false
mirror: always
# Whether we allow AMD switchable graphics.
- name: layers.amd-switchable-gfx.enabled
type: bool

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

@ -450,6 +450,16 @@ void nsHtml5TreeOpExecutor::RunFlushLoop() {
// Now parse content left in the document.write() buffer queue if any.
// This may generate tree ops on its own or dequeue a speculation.
nsresult rv = GetParser()->ParseUntilBlocked();
// ParseUntilBlocked flushes operations from the stage to the OpQueue.
// Those operations may have accompanying speculative operations.
// If so, we have to flush those speculative loads so that we maintain
// the invariant that no speculative load starts after the corresponding
// normal load for the same URL. See
// https://bugzilla.mozilla.org/show_bug.cgi?id=1513292#c80
// for a more detailed explanation of why this is necessary.
FlushSpeculativeLoads();
if (NS_FAILED(rv)) {
MarkAsBroken(rv);
return;

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

@ -874,7 +874,7 @@ FxAccountsInternal.prototype = {
_telemetry: null,
get telemetry() {
if (!this._telemetry) {
this._telemetry = new FxAccountsTelemetry();
this._telemetry = new FxAccountsTelemetry(this);
}
return this._telemetry;
},

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

@ -9,13 +9,25 @@
// sanely shared (eg, services-common?), but let's wait and see where we end up
// first...
// We use this observers module because we leverage its support for richer
// "subject" data.
const { Observers } = ChromeUtils.import(
"resource://services-common/observers.js"
const { XPCOMUtils } = ChromeUtils.import(
"resource://gre/modules/XPCOMUtils.jsm"
);
XPCOMUtils.defineLazyModuleGetters(this, {
log: "resource://gre/modules/FxAccountsCommon.js",
// We use this observers module because we leverage its support for richer
// "subject" data.
Observers: "resource://services-common/observers.js",
Services: "resource://gre/modules/Services.jsm",
});
class FxAccountsTelemetry {
constructor(fxai) {
this._fxai = fxai;
Services.telemetry.setEventRecordingEnabled("fxa", true);
}
// Records an event *in the Fxa/Sync ping*.
recordEvent(object, method, value, extra = undefined) {
// We need to ensure the telemetry module is loaded.
ChromeUtils.import("resource://services-sync/telemetry.js");
@ -50,6 +62,81 @@ class FxAccountsTelemetry {
}
return null;
}
// Record the connection of FxA or one of its services.
// Note that you must call this before performing the actual connection
// or we may record incorrect data - for example, we will not be able to
// determine whether FxA itself was connected before this call.
//
// Currently sends an event in the main telemetry event ping rather than the
// FxA/Sync ping (although this might change in the future)
//
// @param services - An array of service names which should be recorded. FxA
// itself is not counted as a "service" - ie, an empty array should be passed
// if the account is connected without anything else .
//
// @param how - How the connection was done.
async recordConnection(services, how = null) {
try {
let extra = {};
// Record that fxa was connected if it isn't currently - it will be soon.
if (!(await this._fxai.getUserAccountData())) {
extra.fxa = "true";
}
// Events.yaml only declares "sync" as a valid service.
if (services.includes("sync")) {
extra.sync = "true";
}
Services.telemetry.recordEvent("fxa", "connect", "account", how, extra);
} catch (ex) {
log.error("Failed to record connection telemetry", ex);
console.error("Failed to record connection telemetry", ex);
}
}
// Record the disconnection of FxA or one of its services.
// Note that you must call this before performing the actual disconnection
// or we may record incomplete data - for example, if this is called after
// disconnection, we've almost certainly lost the ability to record what
// services were enabled prior to disconnection.
//
// Currently sends an event in the main telemetry event ping rather than the
// FxA/Sync ping (although this might change in the future)
//
// @param service - the service being disconnected. If null, the account
// itself is being disconnected, so all connected services are too.
//
// @param how - how the disconnection was done.
async recordDisconnection(service = null, how = null) {
try {
let extra = {};
if (!service) {
extra.fxa = "true";
// We need a way to enumerate all services - but for now we just hard-code
// all possibilities here.
if (Services.prefs.prefHasUserValue("services.sync.username")) {
extra.sync = "true";
}
} else if (service == "sync") {
extra[service] = "true";
} else {
// Events.yaml only declares "sync" as a valid service.
log.warn(
`recordDisconnection has invalid value for service: ${service}`
);
}
Services.telemetry.recordEvent(
"fxa",
"disconnect",
"account",
how,
extra
);
} catch (ex) {
log.error("Failed to record disconnection telemetry", ex);
console.error("Failed to record disconnection telemetry", ex);
}
}
}
var EXPORTED_SYMBOLS = ["FxAccountsTelemetry"];

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

@ -434,6 +434,11 @@ this.FxAccountsWebChannelHelpers.prototype = {
// Remember who it was so we can log out next time.
this.setPreviousAccountNameHashPref(accountData.email);
await this._fxAccounts.telemetry.recordConnection(
Object.keys(requestedServices || {}),
"webchannel"
);
// A sync-specific hack - we want to ensure sync has been initialized
// before we set the signed-in user.
// XXX - probably not true any more, especially now we have observerPreloads
@ -479,17 +484,15 @@ this.FxAccountsWebChannelHelpers.prototype = {
*
* @param the uid of the account which have been logged out
*/
logout(uid) {
return this._fxAccounts._internal
.getUserAccountData(["uid"])
.then(userData => {
if (userData && userData.uid === uid) {
// true argument is `localOnly`, because server-side stuff
// has already been taken care of by the content server
return fxAccounts.signOut(true);
}
return null;
});
async logout(uid) {
let fxa = this._fxAccounts;
let userData = await fxa._internal.getUserAccountData(["uid"]);
if (userData && userData.uid === uid) {
await fxa.telemetry.recordDisconnection(null, "webchannel");
// true argument is `localOnly`, because server-side stuff
// has already been taken care of by the content server
await fxa.signOut(true);
}
},
/**

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

@ -396,6 +396,9 @@ add_task(async function test_helpers_login_without_customize_sync() {
});
},
},
telemetry: {
recordConnection: sinon.spy(),
},
},
weaveXPCOM: {
whenLoaded() {},
@ -415,6 +418,9 @@ add_task(async function test_helpers_login_without_customize_sync() {
verifiedCanLinkAccount: true,
customizeSync: false,
});
Assert.ok(
helpers._fxAccounts.telemetry.recordConnection.calledWith([], "webchannel")
);
});
add_task(async function test_helpers_login_with_customize_sync() {
@ -433,6 +439,9 @@ add_task(async function test_helpers_login_with_customize_sync() {
});
},
},
telemetry: {
recordConnection: sinon.spy(),
},
},
weaveXPCOM: {
whenLoaded() {},
@ -449,6 +458,9 @@ add_task(async function test_helpers_login_with_customize_sync() {
verifiedCanLinkAccount: true,
customizeSync: true,
});
Assert.ok(
helpers._fxAccounts.telemetry.recordConnection.calledWith([], "webchannel")
);
});
add_task(
@ -469,6 +481,9 @@ add_task(
});
},
},
telemetry: {
recordConnection: sinon.spy(),
},
},
weaveXPCOM: {
whenLoaded() {},
@ -542,6 +557,12 @@ add_task(
);
Assert.equal(Services.prefs.getBoolPref("services.sync.engine.tabs"), true);
Assert.ok(configured, "sync was configured");
Assert.ok(
helpers._fxAccounts.telemetry.recordConnection.calledWith(
["sync"],
"webchannel"
)
);
}
);
@ -556,6 +577,9 @@ add_task(async function test_helpers_login_with_offered_sync_engines() {
resolve(accountData);
},
},
telemetry: {
recordConnection() {},
},
},
weaveXPCOM: {
whenLoaded() {},
@ -610,6 +634,9 @@ add_task(async function test_helpers_login_nothing_offered() {
resolve(accountData);
},
},
telemetry: {
recordConnection() {},
},
},
weaveXPCOM: {
whenLoaded() {},

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

@ -76,11 +76,12 @@ test_valid_value("grid-row", "2 i / auto", "2 i");
test_valid_value("grid-row", "1 / auto", "1");
test_valid_value("grid-column", "2 j / span 3 k");
// https://github.com/w3c/csswg-drafts/issues/2858
// '\\31 st' in Blink, Firefox, '1st' in Edge, '"1st"' in Safari.
test_valid_value("grid-column-end", "\\31st", ["\\31 st", "1st", '"1st"']);
test_valid_value("grid-column-end", "\\31 st", ["\\31 st", "1st", '"1st"']);
// '\\31 st' in Blink, Firefox, EdgeHTML and Safari serialize invalid values.
test_valid_value("grid-column-end", "\\31st", ["\\31 st", "\\31st"]);
test_valid_value("grid-column-end", "\\31 st", ["\\31 st", "\\31st"]);
test_valid_value("grid-column", "\\31st / \\31 st", ["\\31 st", "\\31st"]);
</script>
</body>
</html>

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

@ -656,6 +656,26 @@ pwmgr:
release_channel_collection: opt-out
expiry_version: never
fxa:
connect:
objects: ["account"]
methods: ["connect", "disconnect"]
description: >
Records when a Firefox Account, or a Firefox Account service, is explicitly
connected or disconnected from the browser via an intentional user action.
extra_keys:
fxa: Whether the account itself was connected or disconnected.
sync: Whether sync was connected or disconnected.
products:
- "firefox"
- "fennec"
- "geckoview"
record_in_processes: ["main"]
bug_numbers: [1595954]
notification_emails: ["sync-dev@mozilla.org"]
release_channel_collection: opt-out
expiry_version: never
fxa_avatar_menu:
click:
objects: [

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

@ -54,6 +54,7 @@
#include "mozilla/StaticPrefs_apz.h"
#include "mozilla/StaticPrefs_dom.h"
#include "mozilla/StaticPrefs_layout.h"
#include "mozilla/StaticPrefs_layers.h"
#include "mozilla/Unused.h"
#include "mozilla/IMEStateManager.h"
#include "mozilla/VsyncDispatcher.h"
@ -72,7 +73,6 @@
#include "mozilla/gfx/gfxVars.h"
#include "mozilla/Move.h"
#include "mozilla/Sprintf.h"
#include "mozilla/StaticPrefs_layout.h"
#include "mozilla/webrender/WebRenderTypes.h"
#include "nsRefPtrHashtable.h"
#include "TouchEvents.h"
@ -172,6 +172,7 @@ nsBaseWidget::nsBaseWidget()
mPopupLevel(ePopupLevelTop),
mPopupType(ePopupTypeAny),
mHasRemoteContent(false),
mFissionWindow(false),
mUpdateCursor(true),
mUseAttachedEvents(false),
mIMEHasFocus(false),
@ -391,6 +392,7 @@ void nsBaseWidget::BaseCreate(nsIWidget* aParent, nsWidgetInitData* aInitData) {
mPopupLevel = aInitData->mPopupLevel;
mPopupType = aInitData->mPopupHint;
mHasRemoteContent = aInitData->mHasRemoteContent;
mFissionWindow = aInitData->mFissionWindow;
}
if (aParent) {
@ -1213,7 +1215,11 @@ already_AddRefed<LayerManager> nsBaseWidget::CreateCompositorSession(
bool enableAPZ = UseAPZ();
CompositorOptions options(enableAPZ, enableWR);
bool enableAL = gfx::gfxConfig::IsEnabled(gfx::Feature::ADVANCED_LAYERS);
// Bug 1588484 - Advanced Layers is currently disabled for fission windows,
// since it doesn't properly support nested RefLayers.
bool enableAL =
gfx::gfxConfig::IsEnabled(gfx::Feature::ADVANCED_LAYERS) &&
(!mFissionWindow || StaticPrefs::layers_advanced_fission_enabled());
options.SetUseAdvancedLayers(enableAL);
#ifdef MOZ_WIDGET_ANDROID

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

@ -691,6 +691,7 @@ class nsBaseWidget : public nsIWidget, public nsSupportsWeakReference {
nsPopupType mPopupType;
SizeConstraints mSizeConstraints;
bool mHasRemoteContent;
bool mFissionWindow;
bool mUpdateCursor;
bool mUseAttachedEvents;

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

@ -112,7 +112,8 @@ struct nsWidgetInitData {
mMouseTransparent(false),
mHasRemoteContent(false),
mAlwaysOnTop(false),
mPIPWindow(false) {}
mPIPWindow(false),
mFissionWindow(false) {}
nsWindowType mWindowType;
nsBorderStyle mBorderStyle;
@ -140,6 +141,8 @@ struct nsWidgetInitData {
bool mAlwaysOnTop;
// Is PictureInPicture window
bool mPIPWindow;
// True if fission is enabled for this window
bool mFissionWindow;
};
#endif // nsWidgetInitData_h__

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

@ -593,6 +593,9 @@ nsresult nsAppShellService::JustCreateTopWindow(
if (aChromeMask & nsIWebBrowserChrome::CHROME_ALWAYS_ON_TOP)
widgetInitData.mAlwaysOnTop = true;
if (aChromeMask & nsIWebBrowserChrome::CHROME_FISSION_WINDOW)
widgetInitData.mFissionWindow = true;
#ifdef MOZ_WIDGET_GTK
// Linux/Gtk PIP window support. It's Chrome Toplevel window, always on top
// and without any bar.