Merge mozilla-central to inbound

This commit is contained in:
arthur.iakab 2018-11-08 06:54:25 +02:00
Родитель 3936de51c8 59ae70486b
Коммит 4d18ac7124
44 изменённых файлов: 477 добавлений и 358 удалений

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

@ -636,7 +636,13 @@ var gPopupBlockerObserver = {
var popupButtonText = gNavigatorBundle.getString(stringKey);
var popupButtonAccesskey = gNavigatorBundle.getString(stringKey + ".accesskey");
var messageBase = gNavigatorBundle.getString("popupWarning.message");
let messageBase;
if (popupCount < this.maxReportedPopups) {
messageBase = gNavigatorBundle.getString("popupWarning.message");
} else {
messageBase = gNavigatorBundle.getString("popupWarning.exceeded.message");
}
var message = PluralForm.get(popupCount, messageBase)
.replace("#1", brandShortName)
.replace("#2", popupCount);
@ -840,6 +846,9 @@ var gPopupBlockerObserver = {
},
};
XPCOMUtils.defineLazyPreferenceGetter(gPopupBlockerObserver, "maxReportedPopups",
"privacy.popups.maxReported");
function gKeywordURIFixup({ target: browser, data: fixupInfo }) {
let deserializeURI = (spec) => spec ? makeURI(spec) : null;

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

@ -4,6 +4,7 @@ support-files =
popup_blocker.html
popup_blocker_a.html
popup_blocker_b.html
popup_blocker_10_popups.html
skip-if = (os == 'linux') || (e10s && debug) # Frequent bug 1081925 and bug 1125520 failures
[browser_popup_frames.js]
support-files =

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

@ -14,10 +14,33 @@ function clearAllPermissionsByPrefix(aPrefix) {
}
}
add_task(async function test_opening_blocked_popups() {
add_task(async function setup() {
// Enable the popup blocker.
await SpecialPowers.pushPrefEnv({set: [["dom.disable_open_during_load", true]]});
});
// Tests that we show a special message when popup blocking exceeds
// a certain maximum of popups per page.
add_task(async function test_maximum_reported_blocks() {
Services.prefs.setIntPref("privacy.popups.maxReported", 5);
// Open the test page.
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, baseURL + "popup_blocker_10_popups.html");
// Wait for the popup-blocked notification.
let notification = await BrowserTestUtils.waitForCondition(() =>
gBrowser.getNotificationBox().getNotificationWithValue("popup-blocked"));
// Slightly hacky way to ensure we show the correct message in this case.
ok(notification.label.includes("more than"), "Notification label has 'more than'");
ok(notification.label.includes("5"), "Notification label shows the maximum number of popups");
gBrowser.removeTab(tab);
Services.prefs.clearUserPref("privacy.popups.maxReported");
});
add_task(async function test_opening_blocked_popups() {
// Open the test page.
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, baseURL + "popup_blocker.html");

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

@ -0,0 +1,14 @@
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Page creating ten popups</title>
</head>
<body>
<script type="text/javascript">
for (let i = 0; i < 10; i++) {
window.open("https://example.com");
}
</script>
</body>
</html>

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

@ -254,6 +254,11 @@ lwthemeInstallRequest.allowButton.accesskey2=a
# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
# #1 is brandShortName and #2 is the number of pop-ups blocked.
popupWarning.message=#1 prevented this site from opening a pop-up window.;#1 prevented this site from opening #2 pop-up windows.
# LOCALIZATION NOTE (popupWarning.exceeded.message): Semicolon-separated list of plural forms.
# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
# The singular form is left empty for English, since the number of blocked pop-ups is always greater than 1.
# #1 is brandShortName and #2 is the number of pop-ups blocked.
popupWarning.exceeded.message=;#1 prevented this site from opening more than #2 pop-up windows.
popupWarningButton=Options
popupWarningButton.accesskey=O
popupWarningButtonUnix=Preferences

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

@ -4,6 +4,6 @@
# 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/.
DIRS += ['public', 'src']
DIRS += ['src']
XPCSHELL_TESTS_MANIFESTS += ['test/unit/xpcshell.ini']

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

@ -1,12 +0,0 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
XPIDL_SOURCES += [
'nsIReadConfig.idl',
]
XPIDL_MODULE = 'autoconfig'

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

@ -1,24 +0,0 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsISupports.idl"
%{C++
#define NS_READCONFIG_CID\
{ 0xba5bc4c6,\
0x1dd1, \
0x11b2, \
{ 0xbb, 0x89, 0xb8, 0x44, 0xc6, 0xec, 0x03, 0x39 }\
}
#define NS_READCONFIG_CONTRACTID \
"@mozilla.org/readconfig;1"
%}
[uuid (ba5bc4c6-1dd1-11b2-bb89-b844c6ec0339)]
interface nsIReadConfig : nsISupports {
};

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

@ -7,6 +7,16 @@
#include "nsReadConfig.h"
#include "nsIAppStartupNotifier.h"
#define NS_READCONFIG_CID\
{ 0xba5bc4c6,\
0x1dd1, \
0x11b2, \
{ 0xbb, 0x89, 0xb8, 0x44, 0xc6, 0xec, 0x03, 0x39 }\
}
#define NS_READCONFIG_CONTRACTID \
"@mozilla.org/readconfig;1"
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsReadConfig, Init)
NS_DEFINE_NAMED_CID(NS_READCONFIG_CID);

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

@ -65,7 +65,7 @@ static nsresult DisplayError(void)
// nsISupports Implementation
NS_IMPL_ISUPPORTS(nsReadConfig, nsIReadConfig, nsIObserver)
NS_IMPL_ISUPPORTS(nsReadConfig, nsIObserver)
nsReadConfig::nsReadConfig() :
mRead(false)

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

@ -7,19 +7,16 @@
#define nsReadConfig_h
#include "mozilla/RefPtr.h"
#include "nsIReadConfig.h"
#include "nsAutoConfig.h"
#include "nsIObserver.h"
class nsReadConfig final : public nsIReadConfig,
public nsIObserver
class nsReadConfig final : public nsIObserver
{
public:
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIREADCONFIG
NS_DECL_NSIOBSERVER
nsReadConfig();

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

@ -17,7 +17,7 @@ use internal_types::{FastHashMap, SavedTargetIndex, TextureSource};
use picture::{Picture3DContext, PictureCompositeMode, PicturePrimitive, PictureSurface};
use prim_store::{BrushKind, BrushPrimitive, BrushSegmentTaskId, DeferredResolve};
use prim_store::{EdgeAaSegmentMask, ImageSource, PrimitiveInstanceKind};
use prim_store::{VisibleGradientTile, PrimitiveInstance};
use prim_store::{VisibleGradientTile, PrimitiveInstance, PrimitiveOpacity};
use prim_store::{BrushSegment, BorderSource, PrimitiveDetails};
use render_task::{RenderTaskAddress, RenderTaskId, RenderTaskTree};
use renderer::{BlendMode, ImageBufferKind, ShaderColorMode};
@ -744,8 +744,7 @@ impl AlphaBatchBuilder {
// TODO(gw): We can abstract some of the common code below into
// helper methods, as we port more primitives to make
// use of interning.
let blend_mode = if !prim_instance.opacity.is_opaque ||
let blend_mode = if !prim_data.opacity.is_opaque ||
prim_instance.clip_task_id.is_some() ||
transform_kind == TransformedRectKind::Complex
{
@ -1226,15 +1225,6 @@ impl AlphaBatchBuilder {
let specified_blend_mode = prim_instance.get_blend_mode(&prim.details);
let non_segmented_blend_mode = if !prim_instance.opacity.is_opaque ||
prim_instance.clip_task_id.is_some() ||
transform_kind == TransformedRectKind::Complex
{
specified_blend_mode
} else {
BlendMode::None
};
let prim_header = PrimitiveHeader {
local_rect: prim.local_rect,
local_clip_rect: prim_instance.combined_local_clip_rect,
@ -1251,6 +1241,15 @@ impl AlphaBatchBuilder {
match prim.details {
PrimitiveDetails::Brush(ref brush) => {
let non_segmented_blend_mode = if !brush.opacity.is_opaque ||
prim_instance.clip_task_id.is_some() ||
transform_kind == TransformedRectKind::Complex
{
specified_blend_mode
} else {
BlendMode::None
};
match brush.kind {
BrushKind::Image { alpha_type, request, ref opacity_binding, ref visible_tiles, .. } if !visible_tiles.is_empty() => {
for tile in visible_tiles {
@ -1331,7 +1330,6 @@ impl AlphaBatchBuilder {
self.add_brush_to_batch(
brush,
&params,
prim_instance,
specified_blend_mode,
non_segmented_blend_mode,
prim_header_index,
@ -1391,13 +1389,13 @@ impl AlphaBatchBuilder {
segment_data: &SegmentInstanceData,
segment_index: i32,
batch_kind: BrushBatchKind,
prim_instance: &PrimitiveInstance,
prim_header_index: PrimitiveHeaderIndex,
alpha_blend_mode: BlendMode,
bounding_rect: &WorldRect,
transform_kind: TransformedRectKind,
render_tasks: &RenderTaskTree,
z_id: ZBufferId,
prim_opacity: PrimitiveOpacity,
) {
let clip_task_address = match segment.clip_task_id {
BrushSegmentTaskId::RenderTaskId(id) =>
@ -1407,7 +1405,7 @@ impl AlphaBatchBuilder {
};
let is_inner = segment.edge_flags.is_empty();
let needs_blending = !prim_instance.opacity.is_opaque ||
let needs_blending = !prim_opacity.is_opaque ||
segment.clip_task_id.needs_blending() ||
(!is_inner && transform_kind == TransformedRectKind::Complex);
@ -1439,7 +1437,6 @@ impl AlphaBatchBuilder {
&mut self,
brush: &BrushPrimitive,
params: &BrushBatchParameters,
prim_instance: &PrimitiveInstance,
alpha_blend_mode: BlendMode,
non_segmented_blend_mode: BlendMode,
prim_header_index: PrimitiveHeaderIndex,
@ -1464,13 +1461,13 @@ impl AlphaBatchBuilder {
segment_data,
segment_index as i32,
params.batch_kind,
prim_instance,
prim_header_index,
alpha_blend_mode,
bounding_rect,
transform_kind,
render_tasks,
z_id,
brush.opacity,
);
}
}
@ -1486,13 +1483,13 @@ impl AlphaBatchBuilder {
segment_data,
segment_index as i32,
params.batch_kind,
prim_instance,
prim_header_index,
alpha_blend_mode,
bounding_rect,
transform_kind,
render_tasks,
z_id,
brush.opacity,
);
}
}

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

@ -75,6 +75,8 @@ impl ScrollNodeAndClipChain {
}
}
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[derive(Debug, Copy, Clone)]
pub struct PrimitiveOpacity {
pub is_opaque: bool,
@ -454,6 +456,7 @@ pub struct PrimitiveTemplate {
pub prim_rect: LayoutRect,
pub clip_rect: LayoutRect,
pub kind: PrimitiveTemplateKind,
pub opacity: PrimitiveOpacity,
/// The GPU cache handle for a primitive template. Since this structure
/// is retained across display lists by interning, this GPU cache handle
/// also remains valid, which reduces the number of updates to the GPU
@ -469,6 +472,7 @@ impl From<PrimitiveKey> for PrimitiveTemplate {
clip_rect: LayoutRect::from_au(item.clip_rect),
kind: item.kind.into(),
gpu_cache_handle: GpuCacheHandle::new(),
opacity: PrimitiveOpacity::translucent(),
}
}
}
@ -482,7 +486,7 @@ impl PrimitiveTemplate {
&mut self,
gpu_cache: &mut GpuCache,
) {
match self.kind {
self.opacity = match self.kind {
PrimitiveTemplateKind::Clear => {
if let Some(mut request) = gpu_cache.request(&mut self.gpu_cache_handle) {
// Opaque black with operator dest out
@ -493,6 +497,8 @@ impl PrimitiveTemplate {
[0.0; 4],
);
}
PrimitiveOpacity::translucent()
}
PrimitiveTemplateKind::LineDecoration { ref cache_key, ref color } => {
if let Some(mut request) = gpu_cache.request(&mut self.gpu_cache_handle) {
@ -520,6 +526,11 @@ impl PrimitiveTemplate {
[0.0; 4],
);
}
match cache_key {
Some(..) => PrimitiveOpacity::translucent(),
None => PrimitiveOpacity::from_alpha(color.a),
}
}
PrimitiveTemplateKind::TextRun { ref glyphs, ref font, ref offset, .. } => {
if let Some(mut request) = gpu_cache.request(&mut self.gpu_cache_handle) {
@ -556,9 +567,13 @@ impl PrimitiveTemplate {
assert!(request.current_used_block_num() <= MAX_VERTEX_TEXTURE_WIDTH);
}
PrimitiveOpacity::translucent()
}
PrimitiveTemplateKind::Unused => {}
}
PrimitiveTemplateKind::Unused => {
PrimitiveOpacity::translucent()
}
};
}
}
@ -899,6 +914,7 @@ pub struct BrushSegmentDescriptor {
pub struct BrushPrimitive {
pub kind: BrushKind,
pub opacity: PrimitiveOpacity,
pub segment_desc: Option<BrushSegmentDescriptor>,
}
@ -909,6 +925,7 @@ impl BrushPrimitive {
) -> Self {
BrushPrimitive {
kind,
opacity: PrimitiveOpacity::translucent(),
segment_desc,
}
}
@ -1825,9 +1842,6 @@ pub struct PrimitiveInstance {
/// and per-instance data.
pub gpu_location: GpuCacheHandle,
/// The current opacity of the primitive contents.
pub opacity: PrimitiveOpacity,
/// ID of the clip chain that this primitive is clipped by.
pub clip_chain_id: ClipChainId,
@ -1856,7 +1870,6 @@ impl PrimitiveInstance {
id: PrimitiveDebugId(NEXT_PRIM_ID.fetch_add(1, Ordering::Relaxed)),
clip_task_id: None,
gpu_location: GpuCacheHandle::new(),
opacity: PrimitiveOpacity::translucent(),
clip_chain_id,
spatial_node_index,
cluster_range: ClusterRange { start: 0, end: 0 },
@ -2880,59 +2893,52 @@ impl PrimitiveInstance {
let is_chased = self.is_chased();
self.opacity = match (&mut self.kind, &mut prim_data.kind) {
match (&mut self.kind, &mut prim_data.kind) {
(
PrimitiveInstanceKind::LineDecoration { ref mut cache_handle, .. },
PrimitiveTemplateKind::LineDecoration { ref cache_key, ref color }
PrimitiveTemplateKind::LineDecoration { ref cache_key, .. }
) => {
// Work out the device pixel size to be used to cache this line decoration.
if is_chased {
println!("\tline decoration opaque={}, key={:?}", self.opacity.is_opaque, cache_key);
println!("\tline decoration key={:?}", cache_key);
}
// If we have a cache key, it's a wavy / dashed / dotted line. Otherwise, it's
// a simple solid line.
match cache_key {
Some(cache_key) => {
// TODO(gw): Do we ever need / want to support scales for text decorations
// based on the current transform?
let scale_factor = TypedScale::new(1.0) * frame_context.device_pixel_scale;
let task_size = (LayoutSize::from_au(cache_key.size) * scale_factor).ceil().to_i32();
let surfaces = &mut frame_state.surfaces;
if let Some(cache_key) = cache_key {
// TODO(gw): Do we ever need / want to support scales for text decorations
// based on the current transform?
let scale_factor = TypedScale::new(1.0) * frame_context.device_pixel_scale;
let task_size = (LayoutSize::from_au(cache_key.size) * scale_factor).ceil().to_i32();
let surfaces = &mut frame_state.surfaces;
// Request a pre-rendered image task.
// TODO(gw): This match is a bit untidy, but it should disappear completely
// once the prepare_prims and batching are unified. When that
// happens, we can use the cache handle immediately, and not need
// to temporarily store it in the primitive instance.
*cache_handle = Some(frame_state.resource_cache.request_render_task(
RenderTaskCacheKey {
size: task_size,
kind: RenderTaskCacheKeyKind::LineDecoration(cache_key.clone()),
},
frame_state.gpu_cache,
frame_state.render_tasks,
None,
false,
|render_tasks| {
let task = RenderTask::new_line_decoration(
task_size,
cache_key.style,
cache_key.orientation,
cache_key.wavy_line_thickness.to_f32_px(),
LayoutSize::from_au(cache_key.size),
);
let task_id = render_tasks.add(task);
surfaces[pic_context.surface_index.0].tasks.push(task_id);
task_id
}
));
PrimitiveOpacity::translucent()
}
None => {
PrimitiveOpacity::from_alpha(color.a)
}
// Request a pre-rendered image task.
// TODO(gw): This match is a bit untidy, but it should disappear completely
// once the prepare_prims and batching are unified. When that
// happens, we can use the cache handle immediately, and not need
// to temporarily store it in the primitive instance.
*cache_handle = Some(frame_state.resource_cache.request_render_task(
RenderTaskCacheKey {
size: task_size,
kind: RenderTaskCacheKeyKind::LineDecoration(cache_key.clone()),
},
frame_state.gpu_cache,
frame_state.render_tasks,
None,
false,
|render_tasks| {
let task = RenderTask::new_line_decoration(
task_size,
cache_key.style,
cache_key.orientation,
cache_key.wavy_line_thickness.to_f32_px(),
LayoutSize::from_au(cache_key.size),
);
let task_id = render_tasks.add(task);
surfaces[pic_context.surface_index.0].tasks.push(task_id);
task_id
}
));
}
}
(
@ -2959,8 +2965,6 @@ impl PrimitiveInstance {
frame_state.render_tasks,
frame_state.special_render_passes,
);
PrimitiveOpacity::translucent()
}
(
PrimitiveInstanceKind::Clear,
@ -2968,13 +2972,11 @@ impl PrimitiveInstance {
) => {
// Nothing specific to prepare for clear rects, since the
// GPU cache is updated by the template earlier.
PrimitiveOpacity::translucent()
}
_ => {
unreachable!();
}
};
}
}
fn prepare_prim_for_render_inner(
@ -2995,9 +2997,9 @@ impl PrimitiveInstance {
frame_state.resource_cache,
);
self.opacity = match *prim_details {
match *prim_details {
PrimitiveDetails::Brush(ref mut brush) => {
match brush.kind {
brush.opacity = match brush.kind {
BrushKind::Image {
request,
sub_rect,
@ -3412,9 +3414,9 @@ impl PrimitiveInstance {
opacity_binding.update(frame_context.scene_properties);
PrimitiveOpacity::from_alpha(opacity_binding.current * color.a)
}
}
};
}
};
}
if is_tiled {
// we already requested each tile's gpu data.

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

@ -1 +1 @@
ab887f2ed4d5d378bb7536b1d721bff45c0ad0e6
cd20260979c3eac6f217a416c609d594b4eb1522

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

@ -2768,8 +2768,16 @@ PresShell::FrameNeedsReflow(nsIFrame *aFrame, IntrinsicDirty aIntrinsicDirty,
// ancestor of subtreeRoot.)
for (nsIFrame *a = subtreeRoot;
a && !FRAME_IS_REFLOW_ROOT(a);
a = a->GetParent())
a = a->GetParent()) {
a->MarkIntrinsicISizesDirty();
if (a->HasAnyStateBits(NS_FRAME_OUT_OF_FLOW) &&
a->IsAbsolutelyPositioned()) {
// If we get here, 'a' is abspos, so its subtree's intrinsic sizing
// has no effect on its ancestors' intrinsic sizing. So, don't loop
// upwards any further.
break;
}
}
}
if (aIntrinsicDirty == eStyleChange) {

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

@ -0,0 +1,17 @@
<style>
#a {
-webkit-filter: invert(0);
border-bottom-right-radius: 10px 0px;
overflow: scroll;
height: 50px;
}
.b {
perspective: 4px;
-webkit-mask: url(data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7);
height: 100px;
}
.c { -webkit-transform: scale(-1, 1) }
</style>
<dl id="a">
<dt class="b">
<dialog open="" class="c">

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

@ -542,6 +542,7 @@ load 1467964.html
load 1469354.html
pref(layout.accessiblecaret.enabled,true) load 1472020.html
load 1472027.html
load 1477847.html
load 1489149.html
load 1490037.html
load 1494332.html

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

@ -1142,8 +1142,6 @@ public:
void PositionItemsInCrossAxis(nscoord aLineStartPosition,
const FlexboxAxisTracker& aAxisTracker);
friend class AutoFlexLineListClearer; // (needs access to mItems)
private:
// Helpers for ResolveFlexibleLengths():
void FreezeItemsEarly(bool aIsUsingFlexGrow,
@ -1152,7 +1150,7 @@ private:
void FreezeOrRestoreEachFlexibleSize(const nscoord aTotalViolation,
bool aIsFinalIteration);
LinkedList<FlexItem> mItems; // Linked list of this line's flex items.
AutoCleanLinkedList<FlexItem> mItems; // Linked list of this line's items.
uint32_t mNumItems; // Number of FlexItems in this line (in |mItems|).
// (Shouldn't change after GenerateFlexLines finishes
@ -4539,34 +4537,6 @@ nsFlexContainerFrame::Reflow(nsPresContext* aPresContext,
}
}
// RAII class to clean up a list of FlexLines.
// Specifically, this removes each line from the list, deletes all the
// FlexItems in its list, and deletes the FlexLine.
class MOZ_RAII AutoFlexLineListClearer
{
public:
explicit AutoFlexLineListClearer(LinkedList<FlexLine>& aLines
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
: mLines(aLines)
{
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
}
~AutoFlexLineListClearer()
{
while (FlexLine* line = mLines.popFirst()) {
while (FlexItem* item = line->mItems.popFirst()) {
delete item;
}
delete line;
}
}
private:
LinkedList<FlexLine>& mLines;
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
};
// Class to let us temporarily provide an override value for the the main-size
// CSS property ('width' or 'height') on a flex item, for use in
// nsFrame::ComputeSizeWithIntrinsicDimensions.
@ -4790,9 +4760,8 @@ nsFlexContainerFrame::DoFlexLayout(nsPresContext* aPresContext,
{
MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!");
LinkedList<FlexLine> lines;
AutoCleanLinkedList<FlexLine> lines;
nsTArray<nsIFrame*> placeholderKids;
AutoFlexLineListClearer cleanupLines(lines);
GenerateFlexLines(aPresContext, aReflowInput,
aContentBoxMainSize,

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

@ -9860,6 +9860,10 @@ nsDisplayMasksAndClipPaths::GetLayerState(nsDisplayListBuilder* aBuilder,
bool
nsDisplayMasksAndClipPaths::CanPaintOnMaskLayer(LayerManager* aManager)
{
if (!aManager->IsWidgetLayerManager()) {
return false;
}
if (!nsSVGIntegrationUtils::IsMaskResourceReady(mFrame)) {
return false;
}

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

@ -267,7 +267,6 @@ table {
/* XXXldb do we want this if we're border-collapse:collapse ? */
box-sizing: border-box;
text-indent: 0;
overflow-wrap: normal;
}
table[align="left"] {

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

@ -169,6 +169,7 @@ support-files = file_bug1443344.css
[test_bug1451199-1.html]
[test_bug1451199-2.html]
[test_bug1490890.html]
[test_bug1505254.html]
[test_cascade.html]
[test_ch_ex_no_infloops.html]
[test_change_hint_optimizations.html]

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

@ -0,0 +1,162 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1505254
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1505254</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<style>
/* Note: this CSS/DOM structure is loosely based on WhatsApp Web. */
#outerFlex {
display: flex;
height: 200px;
border: 3px solid purple;
overflow: hidden;
position: relative;
}
#outerItem {
flex: 0 0 60%;
overflow: hidden;
position: relative;
}
#abspos {
position: absolute;
display: flex;
flex-direction: column;
height: 100%;
width: 100%;
}
#insideAbspos {
position: relative;
flex: 1 1 0;
width: 100%;
height: 100%;
}
#scroller {
display: flex;
flex-direction: column;
position: absolute;
top: 0;
overflow-x: hidden;
overflow-y: scroll;
height: 100%;
width: 100%;
}
#initiallyHidden {
display:none;
}
</style>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1505254">Mozilla Bug 1505254</a>
<div id="display">
<div id="content">
<div id="outerFlex">
<div id="outerItem">
<div id="abspos">
<div id="insideAbspos">
<div>
<div id="scroller">
<div style="min-height: 600px">abc</div>
<div id="initiallyHidden">def</div>
</div>
</div>
</div>
<div id="testNode"></div>
</div>
</div>
</div>
</div>
</div>
<pre id="test">
<script type="application/javascript">
"use strict";
/** Test for Bug 1505254 **/
/**
* This test checks how many reflows are required when we make a change inside
* of an abpsos element, which itself is inside of a flex item with cached
* block-size measurements. This test is checking that this sort of change
* doesn't invalidate those cached block-size measurements on the flex item
* ancestor. (We're testing that indirectly by seeing how many frames are
* reflowed.)
*/
const gUtils = SpecialPowers.getDOMWindowUtils(window);
// The elements that we will modify here:
const gInitiallyHidden = document.getElementById("initiallyHidden");
const gTestNode = document.getElementById("testNode");
// Helper function to undo our modifications:
function cleanup()
{
gTestNode.textContent = "";
gInitiallyHidden.style = "";
}
// Helper function to flush layout & return the global frame-reflow-count:
function getReflowCount()
{
let unusedVal = document.getElementById("scroller").offsetHeight; // flush layout
return gUtils.framesReflowed;
}
// This function adds some text in gTestNode and returns the number of frames
// that need to be reflowed as a result of that tweak:
function makeTweakAndCountReflows()
{
let beforeCount = getReflowCount();
gTestNode.textContent = "def";
let afterCount = getReflowCount();
let numReflows = afterCount - beforeCount;
if (numReflows <= 0) {
ok(false, "something's wrong -- we should've reflowed *something*");
}
return numReflows;
}
// ACTUAL TEST LOGIC STARTS HERE
// -----------------------------
// "Reference" measurement: see how many frames need to be reflowed
// in response to a tweak in gTestNode, before we've shown
// #initiallyHidden:
let numReferenceReflows = makeTweakAndCountReflows();
cleanup();
// "Test" measurement: see how many frames need to be reflowed
// in response to a tweak in gTestNode, after we've shown #initiallyHidden:
gInitiallyHidden.style.display = "block";
let numTestReflows = makeTweakAndCountReflows();
cleanup();
// Any difference between our measurements is an indication that we're reflowing
// frames in a non-"dirty" subtree. (The gTestNode tweak has no reason to cause
// #initiallyHidden to be dirty -- and therefore, the presence/absence of
// #initiallyHidden shouldn't affect the number of frames that get reflowed in
// response to the gTestNode tweak).
//
// More importantly: if our measurements differ by *more than 1*, then that
// indicates that we're reflowing the non-"dirty" #initiallyHidden subtree
// *multiple times* in response to the tweak in gTestNode. We definitely want
// to avoid that.
//
// XXXdholbert The "+1" in the is() comparison here is a bit magical, and it
// probably indicates that we are still doing some unnecessary work. But it's
// an improvement -- without the fix that's accompanying this test, we get +5
// reflows here instead of +1. Hopefully we can get rid of the +1 at some point.
is(numTestReflows, numReferenceReflows + 1,
"Tweak should trigger roughly the same number of reflows regardless of " +
"content in unmodified sibling");
</script>
</pre>
</body>
</html>

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

@ -1370,6 +1370,14 @@ pref("content.sink.pending_event_mode", 0);
// 3 = openAbused
pref("privacy.popups.disable_from_plugins", 3);
// Excessive reporting of blocked popups can be a DOS vector,
// by overloading the main process as popups get blocked and when
// users try to restore all popups, which is the most visible
// option in our UI at the time of writing.
// We will invisibly drop any popups from a page that has already
// opened more than this number of popups.
pref("privacy.popups.maxReported", 100);
// send "do not track" HTTP header, disabled by default
pref("privacy.donottrackheader.enabled", false);
// If true, close button will be shown on permission prompts

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

@ -32,20 +32,20 @@ job-defaults:
default:
- raptor/linux_config.py
raptor-tp6-firefox:
description: "Raptor tp6 on Firefox"
try-name: raptor-tp6-firefox
treeherder-symbol: Rap(tp6)
raptor-tp6-1-firefox:
description: "Raptor tp6-1 on Firefox"
try-name: raptor-tp6-1-firefox
treeherder-symbol: Rap(tp6-1)
run-on-projects: built-projects
max-run-time: 1800
mozharness:
extra-options:
- --test=raptor-tp6
- --test=raptor-tp6-1
raptor-tp6-chrome:
description: "Raptor tp6 on Chrome"
try-name: raptor-tp6-chrome
treeherder-symbol: Rap-C(tp6)
raptor-tp6-1-chrome:
description: "Raptor tp6-1 on Chrome"
try-name: raptor-tp6-1-chrome
treeherder-symbol: Rap-C(tp6-1)
run-on-projects: ['try', 'mozilla-central']
tier:
by-test-platform:
@ -54,7 +54,32 @@ raptor-tp6-chrome:
max-run-time: 1200
mozharness:
extra-options:
- --test=raptor-tp6
- --test=raptor-tp6-1
- --app=chrome
raptor-tp6-2-firefox:
description: "Raptor tp6-2 on Firefox"
try-name: raptor-tp6-2-firefox
treeherder-symbol: Rap(tp6-2)
run-on-projects: built-projects
max-run-time: 1200
mozharness:
extra-options:
- --test=raptor-tp6-2
raptor-tp6-2-chrome:
description: "Raptor tp6-2 on Chrome"
try-name: raptor-tp6-2-chrome
treeherder-symbol: Rap-C(tp6-2)
run-on-projects: ['try', 'mozilla-central']
tier:
by-test-platform:
linux64.*: 3
default: 2
max-run-time: 1800
mozharness:
extra-options:
- --test=raptor-tp6-2
- --app=chrome
raptor-speedometer-firefox:
@ -182,28 +207,6 @@ raptor-webaudio-chrome:
- --test=raptor-webaudio
- --app=chrome
raptor-gdocs-firefox:
description: "Raptor gdocs on Firefox"
try-name: raptor-gdocs-firefox
treeherder-symbol: Rap(gdocs)
run-on-projects: built-projects
max-run-time: 1200
mozharness:
extra-options:
- --test=raptor-gdocs
raptor-gdocs-chrome:
description: "Raptor gdocs on Chrome"
try-name: raptor-gdocs-chrome
treeherder-symbol: Rap-C(gdocs)
run-on-projects: ['try', 'mozilla-central']
tier: 2
max-run-time: 1800
mozharness:
extra-options:
- --test=raptor-gdocs
- --app=chrome
raptor-sunspider-firefox:
description: "Raptor SunSpider on Firefox"
try-name: raptor-sunspider-firefox

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

@ -77,24 +77,24 @@ talos:
# - talos-h2 Bug 1487031 - Disabled for not finding actionable regressions
raptor-firefox:
- raptor-tp6-firefox
- raptor-tp6-1-firefox
- raptor-tp6-2-firefox
- raptor-speedometer-firefox
- raptor-stylebench-firefox
- raptor-motionmark-htmlsuite-firefox
- raptor-motionmark-animometer-firefox
- raptor-webaudio-firefox
- raptor-gdocs-firefox
- raptor-sunspider-firefox
- raptor-wasm-godot-firefox
raptor-chrome:
- raptor-tp6-chrome
- raptor-tp6-1-chrome
- raptor-tp6-2-chrome
- raptor-speedometer-chrome
- raptor-stylebench-chrome
- raptor-motionmark-htmlsuite-chrome
- raptor-motionmark-animometer-chrome
- raptor-webaudio-chrome
- raptor-gdocs-chrome
- raptor-sunspider-chrome
- raptor-wasm-godot-chrome

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

@ -1,17 +1,19 @@
# raptor tests
[include:tests/raptor-tp6.ini]
# raptor pageload tests
[include:tests/raptor-tp6-1.ini]
[include:tests/raptor-tp6-2.ini]
# raptor benchmark tests
[include:tests/raptor-assorted-dom.ini]
[include:tests/raptor-motionmark-animometer.ini]
[include:tests/raptor-motionmark-htmlsuite.ini]
[include:tests/raptor-speedometer.ini]
[include:tests/raptor-stylebench.ini]
[include:tests/raptor-sunspider.ini]
[include:tests/raptor-motionmark-htmlsuite.ini]
[include:tests/raptor-motionmark-animometer.ini]
[include:tests/raptor-unity-webgl.ini]
[include:tests/raptor-webaudio.ini]
[include:tests/raptor-gdocs.ini]
[include:tests/raptor-wasm-misc.ini]
[include:tests/raptor-wasm-misc-baseline.ini]
[include:tests/raptor-wasm-misc-ion.ini]
[include:tests/raptor-wasm-godot.ini]
[include:tests/raptor-wasm-godot-baseline.ini]
[include:tests/raptor-wasm-godot-ion.ini]
[include:tests/raptor-assorted-dom.ini]
[include:tests/raptor-wasm-misc.ini]
[include:tests/raptor-wasm-misc-baseline.ini]
[include:tests/raptor-wasm-misc-ion.ini]
[include:tests/raptor-webaudio.ini]

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

@ -2,14 +2,14 @@
# 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/.
# raptor tp6
# raptor tp6-1
[DEFAULT]
type = pageload
playback = mitmproxy
playback_binary_manifest = mitmproxy-rel-bin-{platform}.manifest
python3_win_manifest = python3{x64}.manifest
playback_pageset_manifest = mitmproxy-recordings-raptor-tp6.manifest
playback_pageset_manifest = mitmproxy-recordings-raptor-tp6-1.manifest
page_cycles = 25
unit = ms
lower_is_better = true

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

@ -2,14 +2,14 @@
# 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/.
# raptor gdocs
# raptor tp6-2
[DEFAULT]
type = pageload
playback = mitmproxy
playback_binary_manifest = mitmproxy-rel-bin-{platform}.manifest
python3_win_manifest = python3{x64}.manifest
playback_pageset_manifest = mitmproxy-recordings-raptor-gdocs.manifest
playback_pageset_manifest = mitmproxy-recordings-raptor-tp6-2.manifest
page_cycles = 25
unit = ms
lower_is_better = true
@ -18,42 +18,42 @@ page_timeout = 60000
gecko_profile_interval = 1
gecko_profile_entries = 14000000
[raptor-google-docs-firefox]
[raptor-tp6-docs-firefox]
apps = firefox
test_url = https://docs.google.com/document/d/1US-07msg12slQtI_xchzYxcKlTs6Fp7WqIc6W5GK5M8/edit?usp=sharing
playback_recordings = google-docs.mp
measure = fnbpaint, hero
hero = hero1
[raptor-google-sheets-firefox]
[raptor-tp6-sheets-firefox]
apps = firefox
test_url = https://docs.google.com/spreadsheets/d/1jT9qfZFAeqNoOK97gruc34Zb7y_Q-O_drZ8kSXT-4D4/edit?usp=sharing
playback_recordings = google-sheets.mp
measure = fnbpaint, hero
hero = hero1
[raptor-google-slides-firefox]
[raptor-tp6-slides-firefox]
apps = firefox
test_url = https://docs.google.com/presentation/d/1Ici0ceWwpFvmIb3EmKeWSq_vAQdmmdFcWqaiLqUkJng/edit?usp=sharing
playback_recordings = google-slides.mp
measure = fnbpaint, hero
hero = hero1
[raptor-google-docs-chrome]
[raptor-tp6-docs-chrome]
apps = chrome
test_url = https://docs.google.com/document/d/1US-07msg12slQtI_xchzYxcKlTs6Fp7WqIc6W5GK5M8/edit?usp=sharing
playback_recordings = google-docs.mp
measure = fcp, hero
hero = hero1
[raptor-google-sheets-chrome]
[raptor-tp6-sheets-chrome]
apps = chrome
test_url = https://docs.google.com/spreadsheets/d/1jT9qfZFAeqNoOK97gruc34Zb7y_Q-O_drZ8kSXT-4D4/edit?usp=sharing
playback_recordings = google-sheets.mp
measure = fcp, hero
hero = hero1
[raptor-google-slides-chrome]
[raptor-tp6-slides-chrome]
apps = chrome
test_url = https://docs.google.com/presentation/d/1Ici0ceWwpFvmIb3EmKeWSq_vAQdmmdFcWqaiLqUkJng/edit?usp=sharing
playback_recordings = google-slides.mp

Двоичные данные
testing/raptor/webext/raptor/icon.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 166 B

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

@ -32,6 +32,11 @@
"js": ["benchmark-relay.js"]
}
],
"browser_action": {
"browser_style": true,
"default_icon": "icon.png",
"default_title": "Raptor LOADED"
},
"permissions": [
"<all_urls>",
"tabs",

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

@ -193,6 +193,8 @@ function getBrowserInfo() {
function testTabCreated(tab) {
testTabID = tab.id;
postToControlServer("status", "opened new empty tab " + testTabID);
// update raptor browser toolbar icon text, for a visual indicator when debugging
ext.browserAction.setTitle({title: "Raptor RUNNING"});
}
function testTabRemoved(tab) {
@ -484,7 +486,6 @@ function cleanUp() {
}
function runner() {
console.log("Welcome to Jurassic Park!");
let config = getTestConfig();
console.log("test name is: " + config.test_name);
console.log("test settings url is: " + config.test_settings_url);
@ -495,6 +496,8 @@ function runner() {
benchmarkPort = config.benchmark_port;
postStartupDelay = config.post_startup_delay;
postToControlServer("status", "raptor runner.js is loaded!");
getBrowserInfo().then(function() {
getTestSettings().then(function() {
if (testType == "benchmark") {

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

@ -8,6 +8,7 @@
var EXPORTED_SYMBOLS = ["PopupBlockingChild"];
ChromeUtils.import("resource://gre/modules/ActorChild.jsm");
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
class PopupBlockingChild extends ActorChild {
constructor(dispatcher) {
@ -86,6 +87,11 @@ class PopupBlockingChild extends ActorChild {
this.popupDataInternal = [];
}
// Avoid spamming the parent process with too many blocked popups.
if (this.popupData.length >= PopupBlockingChild.maxReportedPopups) {
return;
}
let obj = {
popupWindowURIspec: ev.popupWindowURI ? ev.popupWindowURI.spec : "about:blank",
popupWindowFeatures: ev.popupWindowFeatures,
@ -135,3 +141,6 @@ class PopupBlockingChild extends ActorChild {
});
}
}
XPCOMUtils.defineLazyPreferenceGetter(PopupBlockingChild, "maxReportedPopups",
"privacy.popups.maxReported");

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

@ -72,14 +72,20 @@ async function getDatabase() {
/**
* Get a transaction for interacting with the study store.
*
* @param {IDBDatabase} db
* @param {String} mode Either "readonly" or "readwrite"
*
* NOTE: Methods on the store returned by this function MUST be called
* synchronously, otherwise the transaction with the store will expire.
* This is why the helper takes a database as an argument; if we fetched the
* database in the helper directly, the helper would be async and the
* transaction would expire before methods on the store were called.
*/
function getStore(db) {
return db.objectStore(STORE_NAME, "readwrite");
function getStore(db, mode) {
if (!mode) {
throw new Error("mode is required");
}
return db.objectStore(STORE_NAME, mode);
}
var AddonStudies = {
@ -99,21 +105,16 @@ var AddonStudies = {
const oldStudies = await AddonStudies.getAll();
let db = await getDatabase();
await AddonStudies.clear();
for (const study of studies) {
await getStore(db).add(study);
}
await AddonStudies.close();
const store = getStore(db, "readwrite");
await Promise.all(studies.map(study => store.add(study)));
try {
await testFunction(...args, studies);
} finally {
db = await getDatabase();
await AddonStudies.clear();
for (const study of oldStudies) {
await getStore(db).add(study);
}
await AddonStudies.close();
const store = getStore(db, "readwrite");
await Promise.all(oldStudies.map(study => store.add(study)));
}
};
};
@ -129,7 +130,6 @@ var AddonStudies = {
await this.markAsEnded(study, "uninstalled-sideload");
}
}
await this.close();
// Listen for add-on uninstalls so we can stop the corresponding studies.
AddonManager.addAddonListener(this);
@ -146,11 +146,7 @@ var AddonStudies = {
const activeStudies = (await this.getAll()).filter(study => study.active);
const matchingStudy = activeStudies.find(study => study.addonId === addon.id);
if (matchingStudy) {
// Use a dedicated DB connection instead of the shared one so that we can
// close it without fear of affecting other users of the shared connection.
const db = await openDatabase();
await this.markAsEnded(matchingStudy, "uninstalled");
await db.close();
}
},
@ -159,19 +155,7 @@ var AddonStudies = {
*/
async clear() {
const db = await getDatabase();
await getStore(db).clear();
},
/**
* Close the current database connection if it is open.
*/
async close() {
if (databasePromise) {
const promise = databasePromise;
databasePromise = null;
const db = await promise;
await db.close();
}
await getStore(db, "readwrite").clear();
},
/**
@ -181,7 +165,7 @@ var AddonStudies = {
*/
async has(recipeId) {
const db = await getDatabase();
const study = await getStore(db).get(recipeId);
const study = await getStore(db, "readonly").get(recipeId);
return !!study;
},
@ -192,7 +176,7 @@ var AddonStudies = {
*/
async get(recipeId) {
const db = await getDatabase();
return getStore(db).get(recipeId);
return getStore(db, "readonly").get(recipeId);
},
/**
@ -201,7 +185,7 @@ var AddonStudies = {
*/
async getAll() {
const db = await getDatabase();
return getStore(db).getAll();
return getStore(db, "readonly").getAll();
},
/**
@ -210,7 +194,7 @@ var AddonStudies = {
*/
async add(study) {
const db = await getDatabase();
return getStore(db).add(study);
return getStore(db, "readwrite").add(study);
},
/**
@ -220,7 +204,7 @@ var AddonStudies = {
*/
async delete(recipeId) {
const db = await getDatabase();
return getStore(db).delete(recipeId);
return getStore(db, "readwrite").delete(recipeId);
},
/**
@ -237,7 +221,7 @@ var AddonStudies = {
study.active = false;
study.studyEndDate = new Date();
const db = await getDatabase();
await getStore(db).put(study);
await getStore(db, "readwrite").put(study);
Services.obs.notifyObservers(study, STUDY_ENDED_TOPIC, `${study.recipeId}`);
TelemetryEvents.sendEvent("unenroll", "addon_study", study.name, {

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

@ -73,14 +73,20 @@ function getDatabase() {
/**
* Get a transaction for interacting with the rollout store.
*
* @param {IDBDatabase} db
* @param {String} mode Either "readonly" or "readwrite"
*
* NOTE: Methods on the store returned by this function MUST be called
* synchronously, otherwise the transaction with the store will expire.
* This is why the helper takes a database as an argument; if we fetched the
* database in the helper directly, the helper would be async and the
* transaction would expire before methods on the store were called.
*/
function getStore(db) {
return db.objectStore(STORE_NAME, "readwrite");
function getStore(db, mode) {
if (!mode) {
throw new Error("mode is required");
}
return db.objectStore(STORE_NAME, mode);
}
var PreferenceRollouts = {
@ -124,7 +130,7 @@ var PreferenceRollouts = {
if (changed) {
const db = await getDatabase();
await getStore(db).put(rollout);
await getStore(db, "readwrite").put(rollout);
}
}
},
@ -146,18 +152,15 @@ var PreferenceRollouts = {
withTestMock(testFunction) {
return async function inner(...args) {
let db = await getDatabase();
const oldData = await getStore(db).getAll();
await getStore(db).clear();
const oldData = await getStore(db, "readonly").getAll();
await getStore(db, "readwrite").clear();
try {
await testFunction(...args);
} finally {
db = await getDatabase();
const store = getStore(db);
let promises = [store.clear()];
for (const d of oldData) {
promises.push(store.add(d));
}
await Promise.all(promises);
await getStore(db, "readwrite").clear();
const store = getStore(db, "readwrite");
await Promise.all(oldData.map(d => store.add(d)));
}
};
},
@ -168,7 +171,7 @@ var PreferenceRollouts = {
*/
async add(rollout) {
const db = await getDatabase();
return getStore(db).add(rollout);
return getStore(db, "readwrite").add(rollout);
},
/**
@ -181,7 +184,7 @@ var PreferenceRollouts = {
throw new Error(`Tried to update ${rollout.slug}, but it doesn't already exist.`);
}
const db = await getDatabase();
return getStore(db).put(rollout);
return getStore(db, "readwrite").put(rollout);
},
/**
@ -191,7 +194,7 @@ var PreferenceRollouts = {
*/
async has(slug) {
const db = await getDatabase();
const rollout = await getStore(db).get(slug);
const rollout = await getStore(db, "readonly").get(slug);
return !!rollout;
},
@ -201,13 +204,13 @@ var PreferenceRollouts = {
*/
async get(slug) {
const db = await getDatabase();
return getStore(db).get(slug);
return getStore(db, "readonly").get(slug);
},
/** Get all rollouts in the database. */
async getAll() {
const db = await getDatabase();
return getStore(db).getAll();
return getStore(db, "readonly").getAll();
},
/** Get all rollouts in the "active" state. */
@ -230,17 +233,4 @@ var PreferenceRollouts = {
}
}
},
/**
* Close the current database connection if it is open. If it is not open,
* this is a no-op.
*/
async closeDB() {
if (databasePromise) {
const promise = databasePromise;
databasePromise = null;
const db = await promise;
await db.close();
}
},
};

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

@ -18,7 +18,6 @@ XPCOMUtils.defineLazyModuleGetters(this, {
NormandyApi: "resource://normandy/lib/NormandyApi.jsm",
ClientEnvironment: "resource://normandy/lib/ClientEnvironment.jsm",
CleanupManager: "resource://normandy/lib/CleanupManager.jsm",
AddonStudies: "resource://normandy/lib/AddonStudies.jsm",
Uptake: "resource://normandy/lib/Uptake.jsm",
ActionsManager: "resource://normandy/lib/ActionsManager.jsm",
});
@ -248,9 +247,6 @@ var RecipeRunner = {
await actions.finalize();
// Close storage connections
await AddonStudies.close();
Uptake.reportRunner(Uptake.RUNNER_SUCCESS);
},

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

@ -69,30 +69,6 @@ decorate_task(
}
);
decorate_task(
AddonStudies.withStudies(),
async function testCloseDatabase() {
await AddonStudies.close();
const openSpy = sinon.spy(IndexedDB, "open");
sinon.assert.notCalled(openSpy);
// Using studies at all should open the database, but only once.
await AddonStudies.has("foo");
await AddonStudies.get("foo");
sinon.assert.calledOnce(openSpy);
// close can be called multiple times
await AddonStudies.close();
await AddonStudies.close();
// After being closed, new operations cause the database to be opened again
await AddonStudies.has("test-study");
sinon.assert.calledTwice(openSpy);
openSpy.restore();
}
);
decorate_task(
AddonStudies.withStudies([
addonStudyFactory({name: "test-study1"}),

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

@ -87,37 +87,6 @@ decorate_task(
}
);
decorate_task(
PreferenceRollouts.withTestMock,
async function testCloseDatabase() {
await PreferenceRollouts.closeDB();
const openSpy = sinon.spy(IndexedDB, "open");
sinon.assert.notCalled(openSpy);
try {
// Using rollouts at all should open the database, but only once.
await PreferenceRollouts.has("foo");
await PreferenceRollouts.get("foo");
sinon.assert.calledOnce(openSpy);
openSpy.reset();
// close can be called multiple times
await PreferenceRollouts.closeDB();
await PreferenceRollouts.closeDB();
// and don't cause the database to be opened (that would be weird)
sinon.assert.notCalled(openSpy);
// After being closed, new operations cause the database to be opened again, but only once
await PreferenceRollouts.has("foo");
await PreferenceRollouts.get("foo");
sinon.assert.calledOnce(openSpy);
} finally {
openSpy.restore();
}
}
);
// recordOriginalValue should update storage to note the original values
decorate_task(
PreferenceRollouts.withTestMock,

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

@ -128,7 +128,6 @@ async function withMockActionSandboxManagers(actions, testFunction) {
}
decorate_task(
withSpy(AddonStudies, "close"),
withStub(Uptake, "reportRunner"),
withStub(NormandyApi, "fetchRecipes"),
withStub(ActionsManager.prototype, "fetchRemoteActions"),
@ -136,7 +135,6 @@ decorate_task(
withStub(ActionsManager.prototype, "runRecipe"),
withStub(ActionsManager.prototype, "finalize"),
async function testRun(
closeSpy,
reportRunnerStub,
fetchRecipesStub,
fetchRemoteActionsStub,
@ -170,16 +168,12 @@ decorate_task(
[[Uptake.RUNNER_SUCCESS]],
"RecipeRunner should report uptake telemetry",
);
// Ensure storage is closed after the run.
ok(closeSpy.calledOnce, "Storage should be closed after the run");
}
);
decorate_task(
withMockNormandyApi,
async function testRunFetchFail(mockApi) {
const closeSpy = sinon.spy(AddonStudies, "close");
const reportRunner = sinon.stub(Uptake, "reportRunner");
const action = {name: "action"};
@ -207,11 +201,6 @@ decorate_task(
sinon.assert.calledWith(reportRunner, Uptake.RUNNER_INVALID_SIGNATURE);
});
// If the recipe fetch failed, we don't need to call close since nothing
// opened a connection in the first place.
sinon.assert.notCalled(closeSpy);
closeSpy.restore();
reportRunner.restore();
}
);

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

@ -3056,11 +3056,13 @@ nsChildView::SetPrefersReducedMotionOverrideForTest(bool aValue)
// it's set in the parent process.
LookAndFeel::SetIntCache(lookAndFeelCache);
if (nsCocoaFeatures::OnMojaveOrLater()) {
if (nsCocoaFeatures::OnMojaveOrLater() &&
NSWorkspaceAccessibilityDisplayOptionsDidChangeNotification) {
[[[NSWorkspace sharedWorkspace] notificationCenter]
postNotificationName: NSWorkspaceAccessibilityDisplayOptionsDidChangeNotification
object:nil];
} else if (nsCocoaFeatures::OnYosemiteOrLater()) {
} else if (nsCocoaFeatures::OnYosemiteOrLater() &&
NSWorkspaceAccessibilityDisplayOptionsDidChangeNotification) {
[[NSNotificationCenter defaultCenter]
postNotificationName: NSWorkspaceAccessibilityDisplayOptionsDidChangeNotification
object:nil];
@ -3315,13 +3317,15 @@ NSEvent* gLastDragMouseDownEvent = nil;
name:NSSystemColorsDidChangeNotification
object:nil];
if (nsCocoaFeatures::OnMojaveOrLater()) {
if (nsCocoaFeatures::OnMojaveOrLater() &&
NSWorkspaceAccessibilityDisplayOptionsDidChangeNotification) {
[[[NSWorkspace sharedWorkspace] notificationCenter]
addObserver:self
selector:@selector(systemMetricsChanged)
name:NSWorkspaceAccessibilityDisplayOptionsDidChangeNotification
object:nil];
} else if (nsCocoaFeatures::OnYosemiteOrLater()) {
} else if (nsCocoaFeatures::OnYosemiteOrLater() &&
NSWorkspaceAccessibilityDisplayOptionsDidChangeNotification) {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(systemMetricsChanged)
name:NSWorkspaceAccessibilityDisplayOptionsDidChangeNotification

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

@ -21,7 +21,7 @@ class nsWaylandDisplay : public nsISupports {
NS_DECL_THREADSAFE_ISUPPORTS
public:
nsWaylandDisplay(wl_display *aDisplay);
explicit nsWaylandDisplay(wl_display *aDisplay);
wl_shm* GetShm();
void SetShm(wl_shm* aShm) { mShm = aShm; };
@ -107,7 +107,7 @@ private:
// and related management
class WindowSurfaceWayland : public WindowSurface {
public:
WindowSurfaceWayland(nsWindow *aWindow);
explicit WindowSurfaceWayland(nsWindow *aWindow);
~WindowSurfaceWayland();
already_AddRefed<gfx::DrawTarget> Lock(const LayoutDeviceIntRegion& aRegion) override;

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

@ -770,7 +770,6 @@ nsRetrievalContextWayland::nsRetrievalContextWayland(void)
, mSeat(nullptr)
, mDataDeviceManager(nullptr)
, mPrimarySelectionDataDeviceManager(nullptr)
, mKeyboard(nullptr)
, mActiveOffers(g_hash_table_new(NULL, NULL))
, mClipboardOffer(nullptr)
, mPrimaryOffer(nullptr)

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

@ -40,7 +40,7 @@ protected:
class WaylandDataOffer : public DataOffer
{
public:
WaylandDataOffer(wl_data_offer* aWaylandDataOffer);
explicit WaylandDataOffer(wl_data_offer* aWaylandDataOffer);
void DragOfferAccept(const char* aMimeType, uint32_t aTime);
void SetDragStatus(GdkDragAction aAction, uint32_t aTime);
@ -63,7 +63,7 @@ private:
class PrimaryDataOffer : public DataOffer
{
public:
PrimaryDataOffer(gtk_primary_selection_offer* aPrimaryDataOffer);
explicit PrimaryDataOffer(gtk_primary_selection_offer* aPrimaryDataOffer);
void SetAvailableDragActions(uint32_t aWaylandActions) {};
virtual ~PrimaryDataOffer();
@ -141,7 +141,6 @@ private:
wl_seat *mSeat;
wl_data_device_manager *mDataDeviceManager;
gtk_primary_selection_device_manager *mPrimarySelectionDataDeviceManager;
wl_keyboard *mKeyboard;
// Data offers provided by Wayland data device
GHashTable* mActiveOffers;