Merge mozilla-central to mozilla-inbound

This commit is contained in:
Carsten "Tomcat" Book 2017-07-06 11:21:11 +02:00
commit 3f89ce0b43
117 changed files with 1242 additions and 1004 deletions

View File

@ -56,7 +56,6 @@ skip-if = (os == 'win' && !debug) # bug 1352668
[browser_ext_contextMenus_checkboxes.js]
[browser_ext_contextMenus_commands.js]
[browser_ext_contextMenus_icons.js]
skip-if = os == 'win' && !debug # Bug 1351638
[browser_ext_contextMenus_onclick.js]
[browser_ext_contextMenus_radioGroups.js]
[browser_ext_contextMenus_uninstall.js]

View File

@ -33,6 +33,7 @@ add_task(async function() {
let extension = ExtensionTestUtils.loadExtension({
manifest: {
"name": "contextMenus commands",
"permissions": ["contextMenus", "activeTab", "tabs"],
"browser_action": {
"default_title": "Test BrowserAction",
@ -59,6 +60,7 @@ add_task(async function() {
async function testContext(id) {
const menu = await openExtensionContextMenu();
const items = menu.getElementsByAttribute("label", id);
is(items.length, 1, `exactly one menu item found`);
await closeExtensionContextMenu(items[0]);
return extension.awaitMessage("test-opened");
}

View File

@ -11,6 +11,7 @@ add_task(async function() {
let extension = ExtensionTestUtils.loadExtension({
manifest: {
"name": "contextMenus icons",
"permissions": ["contextMenus"],
"icons": {
"18": "extension.png",
@ -38,9 +39,10 @@ add_task(async function() {
},
});
let confirmContextMenuIcon = (rootElement) => {
let confirmContextMenuIcon = (rootElements) => {
let expectedURL = new RegExp(String.raw`^moz-extension://[^/]+/extension\.png$`);
let imageUrl = rootElement.getAttribute("image");
is(rootElements.length, 1, "Found exactly one menu item");
let imageUrl = rootElements[0].getAttribute("image");
ok(expectedURL.test(imageUrl), "The context menu should display the extension icon next to the root element");
};
@ -50,17 +52,18 @@ add_task(async function() {
let extensionMenu = await openExtensionContextMenu();
let contextMenu = document.getElementById("contentAreaContextMenu");
let topLevelMenuItem = contextMenu.getElementsByAttribute("ext-type", "top-level-menu")[0];
let topLevelMenuItem = contextMenu.getElementsByAttribute("ext-type", "top-level-menu");
confirmContextMenuIcon(topLevelMenuItem);
let childToDelete = extensionMenu.getElementsByAttribute("label", "child-to-delete")[0];
await closeExtensionContextMenu(childToDelete);
let childToDelete = extensionMenu.getElementsByAttribute("label", "child-to-delete");
is(childToDelete.length, 1, "Found exactly one child to delete");
await closeExtensionContextMenu(childToDelete[0]);
await extension.awaitMessage("child-deleted");
await openExtensionContextMenu();
contextMenu = document.getElementById("contentAreaContextMenu");
topLevelMenuItem = contextMenu.getElementsByAttribute("label", "child")[0];
topLevelMenuItem = contextMenu.getElementsByAttribute("label", "child");
confirmContextMenuIcon(topLevelMenuItem);
await closeContextMenu();

View File

@ -218,6 +218,7 @@ add_task(async function test_onclick_modifiers() {
async function click(modifiers = {}) {
const menu = await openContextMenu();
const items = menu.getElementsByAttribute("label", "modify");
is(items.length, 1, "Got exactly one context menu item");
await closeExtensionContextMenu(items[0], modifiers);
return extension.awaitMessage("click");
}

View File

@ -320,7 +320,7 @@ async function openExtensionContextMenu(selector = "#img1") {
return null;
}
let extensionMenu = topLevelMenu[0].childNodes[0];
let extensionMenu = topLevelMenu[0];
let popupShownPromise = BrowserTestUtils.waitForEvent(contextMenu, "popupshown");
EventUtils.synthesizeMouseAtCenter(extensionMenu, {});
await popupShownPromise;
@ -331,7 +331,10 @@ async function closeExtensionContextMenu(itemToSelect, modifiers = {}) {
let contentAreaContextMenu = document.getElementById("contentAreaContextMenu");
let popupHiddenPromise = BrowserTestUtils.waitForEvent(contentAreaContextMenu, "popuphidden");
EventUtils.synthesizeMouseAtCenter(itemToSelect, modifiers);
return popupHiddenPromise;
await popupHiddenPromise;
// Bug 1351638: parent menu fails to close intermittently, make sure it does.
contentAreaContextMenu.hidePopup();
}
async function openChromeContextMenu(menuId, target, win = window) {

View File

@ -1,5 +1,9 @@
# This file is sourced by the nightly, beta, and release mozconfigs.
# TODO remove once configure defaults to stylo once stylo enabled
# on all platforms.
ac_add_options --enable-stylo=build
. "$topsrcdir/browser/config/mozconfigs/common"
ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}

View File

@ -2,6 +2,10 @@
MOZ_AUTOMATION_L10N_CHECK=0
. "$topsrcdir/browser/config/mozconfigs/common"
# TODO remove once configure defaults to stylo once stylo enabled
# on all platforms.
ac_add_options --enable-stylo=build
ac_add_options --enable-debug
ac_add_options --enable-dmd
ac_add_options --enable-profiling # needed for --enable-dmd to work on Windows

View File

@ -1,5 +1,9 @@
# This file is sourced by the nightly, beta, and release mozconfigs.
# TODO remove once configure defaults to stylo once stylo enabled
# on all platforms.
ac_add_options --enable-stylo=build
. "$topsrcdir/browser/config/mozconfigs/common"
ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}

View File

@ -5,6 +5,10 @@ MOZ_AUTOMATION_L10N_CHECK=0
ac_add_options --target=x86_64-pc-mingw32
ac_add_options --host=x86_64-pc-mingw32
# TODO remove once configure defaults to stylo once stylo enabled
# on all platforms.
ac_add_options --enable-stylo=build
ac_add_options --enable-debug
ac_add_options --enable-dmd
ac_add_options --enable-profiling # needed for --enable-dmd to work on Windows

View File

@ -3,8 +3,8 @@ MOZ_AUTOMATION_L10N_CHECK=0
. "$topsrcdir/build/mozconfig.common"
# Use Clang as specified in manifest
export CC="$topsrcdir/clang/bin/clang -fgnu89-inline -fsanitize-coverage=edge"
export CXX="$topsrcdir/clang/bin/clang++ -fsanitize-coverage=edge"
export CC="$topsrcdir/clang/bin/clang -fgnu89-inline"
export CXX="$topsrcdir/clang/bin/clang++"
export LLVM_SYMBOLIZER="$topsrcdir/clang/bin/llvm-symbolizer"
# Use a newer binutils, from the tooltool gcc package, if it's there

View File

@ -3734,8 +3734,13 @@ Selection::NotifySelectionListeners()
nsCOMPtr<nsIDOMElement> domElementToFocus =
do_QueryInterface(newEditingHost->AsDOMNode());
// Note that don't steal focus from focused window if the window doesn't
// have focus.
fm->SetFocus(domElementToFocus, nsIFocusManager::FLAG_NOSWITCHFRAME);
// have focus and if the window isn't focused window, shouldn't be
// scrolled to the new focused element.
uint32_t flags = nsIFocusManager::FLAG_NOSWITCHFRAME;
if (focusedWindow != fm->GetFocusedWindow()) {
flags |= nsIFocusManager::FLAG_NOSCROLL;
}
fm->SetFocus(domElementToFocus, flags);
}
}
}

View File

@ -7,6 +7,7 @@
#ifndef MOZILLA_DOM_OFFSCREENCANVAS_H_
#define MOZILLA_DOM_OFFSCREENCANVAS_H_
#include "gfxTypes.h"
#include "mozilla/DOMEventTargetHelper.h"
#include "mozilla/layers/LayersTypes.h"
#include "mozilla/RefPtr.h"

View File

@ -62,7 +62,6 @@
#include "mozilla/loader/ScriptCacheActors.h"
#include "mozilla/net/NeckoChild.h"
#include "mozilla/net/CaptivePortalService.h"
#include "mozilla/Omnijar.h"
#include "mozilla/plugins/PluginInstanceParent.h"
#include "mozilla/plugins/PluginModuleParent.h"
#include "mozilla/widget/ScreenManager.h"
@ -1436,18 +1435,6 @@ GetAppPaths(nsCString &aAppPath, nsCString &aAppBinaryPath, nsCString &aAppDir)
return true;
}
// Returns whether or not the currently running build is a development build -
// where development build means "the files in the .app are symlinks to the src
// directory". This check is implemented by looking for omni.ja in
// .app/Contents/Resources/.
static bool
IsDevelopmentBuild()
{
nsCOMPtr<nsIFile> path = mozilla::Omnijar::GetPath(mozilla::Omnijar::GRE);
// If the path doesn't exist, we're a dev build.
return path == nullptr;
}
// This function is only used in an |#ifdef DEBUG| path.
#ifdef DEBUG
// Given a path to a file, return the directory which contains it.
@ -1517,7 +1504,7 @@ StartMacOSContentSandbox()
bool isFileProcess = cc->GetRemoteType().EqualsLiteral(FILE_REMOTE_TYPE);
char *developer_repo_dir = nullptr;
if (IsDevelopmentBuild()) {
if (mozilla::IsDevelopmentBuild()) {
// If this is a developer build the resources in the .app are symlinks to
// outside of the .app. Therefore in non-release builds we allow reads from
// the whole repository. MOZ_DEVELOPER_REPO_DIR is set by mach run.

View File

@ -1369,11 +1369,6 @@ TabChild::RecvHandleTap(const GeckoContentController::TapType& aType,
mAPZEventState->ProcessLongTapUp(presShell, point, scale, aModifiers);
}
break;
case GeckoContentController::TapType::eSentinel:
// Should never happen, but we need to handle this case to make the compiler
// happy.
MOZ_ASSERT(false);
break;
}
return IPC_OK();
}

View File

@ -11,6 +11,10 @@
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/Logging.h"
#include "mozilla/Telemetry.h"
#include "mozilla/Services.h"
#include "nsIObserver.h"
#include "nsIObserverService.h"
#include "nsWeakReference.h"
#include "prsystem.h"
namespace mozilla {

View File

@ -91,6 +91,17 @@ public:
return retSize;
}
/**
* In most cases you probably want to use TransformBounds. This function
* just transforms the top-left and size separately and constructs a rect
* from those results.
*/
MatrixRect TransformRect(const MatrixRect& aRect) const
{
return MatrixRect(TransformPoint(aRect.TopLeft()),
TransformSize(aRect.Size()));
}
GFX2D_API MatrixRect TransformBounds(const MatrixRect& aRect) const
{
int i;

View File

@ -8,6 +8,7 @@
#include <stdint.h> // for uint32_t, uint64_t
#include "Units.h" // for CSSRect, CSSPixel, etc
#include "mozilla/DefineEnum.h" // for MOZ_DEFINE_ENUM
#include "mozilla/HashFunctions.h" // for HashGeneric
#include "mozilla/Maybe.h"
#include "mozilla/gfx/BasePoint.h" // for BasePoint
@ -50,23 +51,22 @@ public:
static const ViewID START_SCROLL_ID = 2; // This is the ID that scrolling subframes
// will begin at.
enum ScrollOffsetUpdateType : uint8_t {
eNone, // The default; the scroll offset was not updated
eMainThread, // The scroll offset was updated by the main thread.
ePending, // The scroll offset was updated on the main thread, but not
// painted, so the layer texture data is still at the old
// offset.
eUserAction, // In an APZ repaint request, this means the APZ generated
// the scroll position based on user action (the alternative
// is eNone which means it's just request a repaint because
// it got a scroll update from the main thread).
eRestore, // The scroll offset was updated by the main thread, but as
// a restore from history or after a frame reconstruction.
// In this case, APZ can ignore the offset change if the
// user has done an APZ scroll already.
eSentinel // For IPC use only
};
MOZ_DEFINE_ENUM_WITH_BASE_AT_CLASS_SCOPE(
ScrollOffsetUpdateType, uint8_t, (
eNone, // The default; the scroll offset was not updated
eMainThread, // The scroll offset was updated by the main thread.
ePending, // The scroll offset was updated on the main thread, but not
// painted, so the layer texture data is still at the old
// offset.
eUserAction, // In an APZ repaint request, this means the APZ generated
// the scroll position based on user action (the alternative
// is eNone which means it's just request a repaint because
// it got a scroll update from the main thread).
eRestore // The scroll offset was updated by the main thread, but as
// a restore from history or after a frame reconstruction.
// In this case, APZ can ignore the offset change if the
// user has done an APZ scroll already.
));
FrameMetrics()
: mScrollId(NULL_SCROLL_ID)

View File

@ -16,6 +16,7 @@
#include "gfxQuad.h" // for gfxQuad
#include "gfxRect.h" // for gfxRect
#include "gfxTypes.h" // for gfxFloat
#include "gfxUtils.h" // for TransformToQuad
#include "mozilla/gfx/BasePoint3D.h" // for BasePoint3D
#include "mozilla/Sprintf.h" // for SprintfLiteral
#include "nsRegion.h" // for nsIntRegion
@ -89,8 +90,8 @@ static LayerSortOrder CompareDepth(Layer* aOne, Layer* aTwo) {
aTwo->GetLocalTransform() * aTwo->GetParent()->GetEffectiveTransform();
// Transform both rectangles and project into 2d space.
gfxQuad ourTransformedRect = ourRect.TransformToQuad(ourTransform);
gfxQuad otherTransformedRect = otherRect.TransformToQuad(otherTransform);
gfxQuad ourTransformedRect = gfxUtils::TransformToQuad(ourRect, ourTransform);
gfxQuad otherTransformedRect = gfxUtils::TransformToQuad(otherRect, otherTransform);
gfxRect ourBounds = ourTransformedRect.GetBounds();
gfxRect otherBounds = otherTransformedRect.GetBounds();

View File

@ -9,6 +9,7 @@
#include <stdint.h> // for uint32_t
#include "Units.h"
#include "mozilla/DefineEnum.h" // for MOZ_DEFINE_ENUM
#include "mozilla/gfx/Point.h" // for IntPoint
#include "mozilla/Maybe.h"
#include "mozilla/TypedEnumBits.h"
@ -72,12 +73,12 @@ enum class SurfaceMode : int8_t {
SURFACE_COMPONENT_ALPHA
};
enum class ScaleMode : int8_t {
SCALE_NONE,
STRETCH,
SENTINEL
MOZ_DEFINE_ENUM_CLASS_WITH_BASE(
ScaleMode, int8_t, (
SCALE_NONE,
STRETCH
// Unimplemented - PRESERVE_ASPECT_RATIO_CONTAIN
};
));
struct EventRegions {
// The hit region for a layer contains all areas on the layer that are
@ -304,12 +305,11 @@ private:
uint64_t mHandle;
};
enum class ScrollDirection : uint32_t {
MOZ_DEFINE_ENUM_CLASS_WITH_BASE(ScrollDirection, uint32_t, (
NONE,
VERTICAL,
HORIZONTAL,
SENTINEL /* for IPC serialization */
};
HORIZONTAL
));
enum class CSSFilterType : int8_t {
BLUR,

View File

@ -11,6 +11,7 @@
#include "InputData.h" // for PinchGestureInput
#include "Units.h" // for CSSPoint, CSSRect, etc
#include "mozilla/Assertions.h" // for MOZ_ASSERT_HELPER2
#include "mozilla/DefineEnum.h" // for MOZ_DEFINE_ENUM
#include "mozilla/EventForwards.h" // for Modifiers
#include "nsISupportsImpl.h"
@ -49,15 +50,14 @@ public:
* a click event with detail=2 to web content (similar to what a mouse double-
* click would do).
*/
enum class TapType {
eSingleTap,
eDoubleTap,
eSecondTap,
eLongTap,
eLongTapUp,
eSentinel,
};
MOZ_DEFINE_ENUM_CLASS_AT_CLASS_SCOPE(
TapType, (
eSingleTap,
eDoubleTap,
eSecondTap,
eLongTap,
eLongTapUp
));
/**
* Requests handling of a tap event. |aPoint| is in LD pixels, relative to the
@ -107,34 +107,32 @@ public:
*/
virtual void DispatchToRepaintThread(already_AddRefed<Runnable> aTask) = 0;
enum class APZStateChange {
/**
* APZ started modifying the view (including panning, zooming, and fling).
*/
eTransformBegin,
/**
* APZ finished modifying the view.
*/
eTransformEnd,
/**
* APZ started a touch.
* |aArg| is 1 if touch can be a pan, 0 otherwise.
*/
eStartTouch,
/**
* APZ started a pan.
*/
eStartPanning,
/**
* APZ finished processing a touch.
* |aArg| is 1 if touch was a click, 0 otherwise.
*/
eEndTouch,
MOZ_DEFINE_ENUM_CLASS_AT_CLASS_SCOPE(
APZStateChange, (
/**
* APZ started modifying the view (including panning, zooming, and fling).
*/
eTransformBegin,
/**
* APZ finished modifying the view.
*/
eTransformEnd,
/**
* APZ started a touch.
* |aArg| is 1 if touch can be a pan, 0 otherwise.
*/
eStartTouch,
/**
* APZ started a pan.
*/
eStartPanning,
/**
* APZ finished processing a touch.
* |aArg| is 1 if touch was a click, 0 otherwise.
*/
eEndTouch
));
// Sentinel value for IPC, this must be the last item in the enum and
// should not be used as an actual message value.
eSentinel
};
/**
* General notices of APZ state changes for consumers.
* |aGuid| identifies the APZC originating the state change.

View File

@ -1305,10 +1305,6 @@ APZCTreeManager::ReceiveInputEvent(InputData& aEvent,
targetGuid = mFocusState.GetVerticalTarget();
break;
}
case KeyboardScrollAction::eSentinel: {
MOZ_ASSERT_UNREACHABLE("Invalid KeyboardScrollActionType");
}
}
// If we don't have a scroll target then either we have a stale focus target,
@ -1347,9 +1343,6 @@ APZCTreeManager::ReceiveInputEvent(InputData& aEvent,
keyInput.mHandledByAPZ = true;
focusSetter.MarkAsNonFocusChanging();
break;
} case SENTINEL_INPUT: {
MOZ_ASSERT_UNREACHABLE("Invalid InputType.");
break;
}
}

View File

@ -131,8 +131,6 @@ AndroidDynamicToolbarAnimator::ReceiveInputEvent(InputData& aEvent, const Screen
case MultiTouchInput::MULTITOUCH_CANCEL:
mControllerTouchCount -= multiTouch.mTouches.Length();
break;
case MultiTouchInput::MULTITOUCH_SENTINEL:
MOZ_FALLTHROUGH_ASSERT("Invalid value");
case MultiTouchInput::MULTITOUCH_MOVE:
break;
}
@ -203,9 +201,6 @@ AndroidDynamicToolbarAnimator::ReceiveInputEvent(InputData& aEvent, const Screen
HandleTouchEnd(currentToolbarState, currentTouch);
}
break;
case MultiTouchInput::MULTITOUCH_SENTINEL:
MOZ_ASSERT_UNREACHABLE("Invalid value");
break;
}
TranslateTouchEvent(multiTouch);

View File

@ -903,9 +903,9 @@ nsEventStatus AsyncPanZoomController::HandleDragEvent(const MouseInput& aEvent,
CSSCoord minScrollPosition =
GetAxisStart(aDragMetrics.mDirection, mFrameMetrics.GetScrollableRect().TopLeft());
CSSCoord maxScrollPosition =
GetAxisLength(aDragMetrics.mDirection, mFrameMetrics.GetScrollableRect()) -
GetAxisStart(aDragMetrics.mDirection, mFrameMetrics.GetScrollableRect().BottomRight()) -
GetAxisLength(aDragMetrics.mDirection, mFrameMetrics.CalculateCompositedRectInCssPixels());
CSSCoord scrollPosition = scrollPercent * maxScrollPosition;
CSSCoord scrollPosition = minScrollPosition + (scrollPercent * (maxScrollPosition - minScrollPosition));
scrollPosition = std::max(scrollPosition, minScrollPosition);
scrollPosition = std::min(scrollPosition, maxScrollPosition);
@ -949,7 +949,6 @@ nsEventStatus AsyncPanZoomController::HandleInputEvent(const InputData& aEvent,
case MultiTouchInput::MULTITOUCH_MOVE: rv = OnTouchMove(multiTouchInput); break;
case MultiTouchInput::MULTITOUCH_END: rv = OnTouchEnd(multiTouchInput); break;
case MultiTouchInput::MULTITOUCH_CANCEL: rv = OnTouchCancel(multiTouchInput); break;
case MultiTouchInput::MULTITOUCH_SENTINEL: MOZ_ASSERT_UNREACHABLE("Invalid value"); break;
}
break;
}
@ -968,7 +967,6 @@ nsEventStatus AsyncPanZoomController::HandleInputEvent(const InputData& aEvent,
case PanGestureInput::PANGESTURE_MOMENTUMSTART: rv = OnPanMomentumStart(panGestureInput); break;
case PanGestureInput::PANGESTURE_MOMENTUMPAN: rv = OnPan(panGestureInput, false); break;
case PanGestureInput::PANGESTURE_MOMENTUMEND: rv = OnPanMomentumEnd(panGestureInput); break;
case PanGestureInput::PANGESTURE_SENTINEL: MOZ_ASSERT_UNREACHABLE("Invalid value"); break;
}
break;
}
@ -1011,10 +1009,6 @@ nsEventStatus AsyncPanZoomController::HandleInputEvent(const InputData& aEvent,
rv = OnKeyboard(keyInput);
break;
}
case SENTINEL_INPUT: {
MOZ_ASSERT_UNREACHABLE("Invalid value");
break;
}
}
return rv;
@ -1033,7 +1027,6 @@ nsEventStatus AsyncPanZoomController::HandleGestureEvent(const InputData& aEvent
case PinchGestureInput::PINCHGESTURE_START: rv = OnScaleBegin(pinchGestureInput); break;
case PinchGestureInput::PINCHGESTURE_SCALE: rv = OnScale(pinchGestureInput); break;
case PinchGestureInput::PINCHGESTURE_END: rv = OnScaleEnd(pinchGestureInput); break;
case PinchGestureInput::PINCHGESTURE_SENTINEL: MOZ_ASSERT_UNREACHABLE("Invalid value"); break;
}
break;
}
@ -1047,7 +1040,6 @@ nsEventStatus AsyncPanZoomController::HandleGestureEvent(const InputData& aEvent
case TapGestureInput::TAPGESTURE_DOUBLE: rv = OnDoubleTap(tapGestureInput); break;
case TapGestureInput::TAPGESTURE_SECOND: rv = OnSecondTap(tapGestureInput); break;
case TapGestureInput::TAPGESTURE_CANCEL: rv = OnCancelTap(tapGestureInput); break;
case TapGestureInput::TAPGESTURE_SENTINEL: MOZ_ASSERT_UNREACHABLE("Invalid value"); break;
}
break;
}
@ -1610,10 +1602,6 @@ AsyncPanZoomController::GetScrollWheelDelta(const ScrollWheelInput& aEvent) cons
delta = ToParentLayerCoordinates(ScreenPoint(aEvent.mDeltaX, aEvent.mDeltaY), aEvent.mOrigin);
break;
}
case ScrollWheelInput::SCROLLDELTA_SENTINEL: {
MOZ_ASSERT_UNREACHABLE("Invalid value");
break;
}
}
// Apply user-set multipliers.
@ -1687,10 +1675,6 @@ void ReportKeyboardScrollAction(const KeyboardScrollAction& aAction)
scrollMethod = ScrollInputMethod::ApzCompleteScroll;
break;
}
case KeyboardScrollAction::eSentinel: {
MOZ_ASSERT_UNREACHABLE("Invalid KeyboardScrollAction.");
return;
}
}
mozilla::Telemetry::Accumulate(mozilla::Telemetry::SCROLL_INPUT_METHODS,
@ -1816,8 +1800,6 @@ AsyncPanZoomController::GetKeyboardDestination(const KeyboardScrollAction& aActi
}
break;
}
case KeyboardScrollAction::eSentinel:
MOZ_ASSERT_UNREACHABLE("unexpected keyboard delta type");
}
return scrollDestination;
@ -1863,7 +1845,6 @@ AsyncPanZoomController::CanScroll(ScrollDirection aDirection) const
case ScrollDirection::VERTICAL: return mY.CanScroll();
case ScrollDirection::NONE:
case ScrollDirection::SENTINEL:
MOZ_ASSERT_UNREACHABLE("Invalid value");
break;
}
@ -1907,8 +1888,6 @@ ScrollInputMethodForWheelDeltaType(ScrollWheelInput::ScrollDeltaType aDeltaType)
case ScrollWheelInput::SCROLLDELTA_PIXEL: {
return ScrollInputMethod::ApzWheelPixel;
}
case ScrollWheelInput::SCROLLDELTA_SENTINEL:
break;
}
MOZ_ASSERT_UNREACHABLE("Invalid value");
return ScrollInputMethod::ApzWheelLine;
@ -2023,11 +2002,6 @@ nsEventStatus AsyncPanZoomController::OnScrollWheel(const ScrollWheelInput& aEve
animation->UpdateDelta(aEvent.mTimeStamp, deltaInAppUnits, nsSize(velocity.x, velocity.y));
break;
}
case ScrollWheelInput::SCROLLMODE_SENTINEL: {
MOZ_ASSERT_UNREACHABLE("Invalid ScrollMode.");
break;
}
}
return nsEventStatus_eConsumeNoDefault;

View File

@ -159,7 +159,7 @@ CheckerboardEvent::StartEvent()
}
MonitorAutoLock lock(mRendertraceLock);
std::vector<PropertyValue> history;
for (int i = 0; i < MAX_RendertraceProperty; i++) {
for (size_t i = 0; i < sRendertracePropertyCount; i++) {
mBufferedProperties[i].Flush(history, lock);
}
std::sort(history.begin(), history.end());

View File

@ -6,6 +6,7 @@
#ifndef mozilla_layers_CheckerboardEvent_h
#define mozilla_layers_CheckerboardEvent_h
#include "mozilla/DefineEnum.h"
#include "mozilla/Monitor.h"
#include "mozilla/TimeStamp.h"
#include <sstream>
@ -25,19 +26,17 @@ namespace layers {
*/
class CheckerboardEvent {
public:
enum RendertraceProperty {
Page,
PaintedCriticalDisplayPort,
PaintedDisplayPort,
RequestedDisplayPort,
UserVisible,
MOZ_DEFINE_ENUM_AT_CLASS_SCOPE(
RendertraceProperty, (
Page,
PaintedCriticalDisplayPort,
PaintedDisplayPort,
RequestedDisplayPort,
UserVisible
));
// sentinel final value
MAX_RendertraceProperty
};
static const char* sDescriptions[MAX_RendertraceProperty];
static const char* sColors[MAX_RendertraceProperty];
static const char* sDescriptions[sRendertracePropertyCount];
static const char* sColors[sRendertracePropertyCount];
public:
explicit CheckerboardEvent(bool aRecordTrace);
@ -207,7 +206,7 @@ private:
* checkerboarding actually starts, so that we have some data on what
* was happening before the checkerboarding started.
*/
PropertyBuffer mBufferedProperties[MAX_RendertraceProperty];
PropertyBuffer mBufferedProperties[sRendertracePropertyCount];
/**
* The rendertrace info buffer that gives us info on what was happening
* during the checkerboard event.

View File

@ -113,9 +113,6 @@ FocusState::Update(uint64_t aRootLayerTreeId,
mLastContentProcessedEvent = target.mSequenceNumber;
return;
}
case FocusTarget::eSentinel: {
MOZ_ASSERT_UNREACHABLE("Invalid FocusTargetType");
}
}
}
}

View File

@ -8,7 +8,8 @@
#include <stdint.h> // for int32_t, uint32_t
#include "FrameMetrics.h" // for FrameMetrics::ViewID
#include "FrameMetrics.h" // for FrameMetrics::ViewID
#include "mozilla/DefineEnum.h" // for MOZ_DEFINE_ENUM
class nsIPresShell;
@ -30,15 +31,13 @@ public:
FrameMetrics::ViewID mVertical;
};
enum FocusTargetType
{
eNone,
eRefLayer,
eScrollLayer,
MOZ_DEFINE_ENUM_AT_CLASS_SCOPE(
FocusTargetType, (
eNone,
eRefLayer,
eScrollLayer
));
// Used as an upper bound for ContiguousEnumSerializer
eSentinel,
};
union FocusTargetData
{
uint64_t mRefLayerId;

View File

@ -146,9 +146,6 @@ nsEventStatus GestureEventListener::HandleInputEvent(const MultiTouchInput& aEve
mTouches.Clear();
rv = HandleInputTouchCancel();
break;
case MultiTouchInput::MULTITOUCH_SENTINEL:
MOZ_ASSERT_UNREACHABLE("Invalid MultTouchInput.");
break;
}
return rv;

View File

@ -20,9 +20,6 @@ KeyboardScrollAction::GetScrollUnit(KeyboardScrollAction::KeyboardScrollActionTy
return nsIScrollableFrame::PAGES;
case KeyboardScrollAction::eScrollComplete:
return nsIScrollableFrame::WHOLE;
case KeyboardScrollAction::eSentinel:
MOZ_ASSERT_UNREACHABLE("Invalid KeyboardScrollActionType.");
return nsIScrollableFrame::WHOLE;
}
// Silence an overzealous warning

View File

@ -6,6 +6,7 @@
#ifndef mozilla_layers_KeyboardScrollAction_h
#define mozilla_layers_KeyboardScrollAction_h
#include "mozilla/DefineEnum.h" // for MOZ_DEFINE_ENUM
#include "nsIScrollableFrame.h" // for nsIScrollableFrame::ScrollUnit
namespace mozilla {
@ -17,16 +18,13 @@ namespace layers {
struct KeyboardScrollAction final
{
public:
enum KeyboardScrollActionType : uint8_t
{
eScrollCharacter,
eScrollLine,
eScrollPage,
eScrollComplete,
// Used as an upper bound for ContiguousEnumSerializer
eSentinel,
};
MOZ_DEFINE_ENUM_WITH_BASE_AT_CLASS_SCOPE(
KeyboardScrollActionType, uint8_t, (
eScrollCharacter,
eScrollLine,
eScrollPage,
eScrollComplete
));
static nsIScrollableFrame::ScrollUnit
GetScrollUnit(KeyboardScrollActionType aDeltaType);

View File

@ -33,9 +33,6 @@ KeyboardScrollAnimation::KeyboardScrollAnimation(AsyncPanZoomController& aApzc,
mOriginMinMS = clamped(gfxPrefs::OtherSmoothScrollMinDurationMs(), 0, mOriginMaxMS);
break;
}
case KeyboardScrollAction::eSentinel: {
MOZ_ASSERT_UNREACHABLE("Invalid KeyboardScrollActionType.");
}
}
// The pref is 100-based int percentage, while mIntervalRatio is 1-based ratio

View File

@ -37,9 +37,6 @@ TouchCounter::Update(const MultiTouchInput& aInput)
break;
case MultiTouchInput::MULTITOUCH_MOVE:
break;
case MultiTouchInput::MULTITOUCH_SENTINEL:
MOZ_ASSERT_UNREACHABLE("Invalid input");
break;
}
}

View File

@ -29,8 +29,6 @@ WheelScrollAnimation::WheelScrollAnimation(AsyncPanZoomController& aApzc,
mOriginMaxMS = clamped(gfxPrefs::PixelSmoothScrollMaxDurationMs(), 0, 10000);
mOriginMinMS = clamped(gfxPrefs::PixelSmoothScrollMinDurationMs(), 0, mOriginMaxMS);
break;
case ScrollWheelInput::SCROLLDELTA_SENTINEL:
MOZ_FALLTHROUGH_ASSERT("Invalid value");
case ScrollWheelInput::SCROLLDELTA_LINE:
mOriginMaxMS = clamped(gfxPrefs::WheelSmoothScrollMaxDurationMs(), 0, 10000);
mOriginMinMS = clamped(gfxPrefs::WheelSmoothScrollMinDurationMs(), 0, mOriginMaxMS);

View File

@ -272,9 +272,6 @@ public:
case ScrollDirection::VERTICAL:
EXPECT_EQ(PANNING_LOCKED_Y, mState);
break;
case ScrollDirection::SENTINEL:
MOZ_ASSERT(false, "Invalid value");
break;
}
}

View File

@ -975,9 +975,6 @@ APZCCallbackHelper::NotifyPinchGesture(PinchGestureInput::PinchGestureType aType
case PinchGestureInput::PINCHGESTURE_END:
msg = eMagnifyGesture;
break;
case PinchGestureInput::PINCHGESTURE_SENTINEL:
MOZ_ASSERT_UNREACHABLE("Invalid value");
return;
}
WidgetSimpleGestureEvent event(true, msg, aWidget);

View File

@ -490,11 +490,6 @@ APZEventState::ProcessAPZStateChange(ViewID aViewId,
mActiveElementManager->HandleTouchEnd();
break;
}
case APZStateChange::eSentinel:
// Should never happen, but we want this case branch to stop the compiler
// whining about unhandled values.
MOZ_ASSERT(false);
break;
}
}

View File

@ -217,11 +217,6 @@ ChromeProcessController::HandleTap(TapType aType,
case TapType::eLongTapUp:
mAPZEventState->ProcessLongTapUp(presShell, point, scale, aModifiers);
break;
case TapType::eSentinel:
// Should never happen, but we need to handle this case branch for the
// compiler to be happy.
MOZ_ASSERT(false);
break;
}
}

View File

@ -42,10 +42,10 @@ struct ParamTraits<mozilla::layers::LayersBackend>
template <>
struct ParamTraits<mozilla::layers::ScaleMode>
: public ContiguousEnumSerializer<
: public ContiguousEnumSerializerInclusive<
mozilla::layers::ScaleMode,
mozilla::layers::ScaleMode::SCALE_NONE,
mozilla::layers::ScaleMode::SENTINEL>
mozilla::layers::kHighestScaleMode>
{};
template <>
@ -64,18 +64,18 @@ struct ParamTraits<mozilla::layers::DiagnosticTypes>
template <>
struct ParamTraits<mozilla::layers::ScrollDirection>
: public ContiguousEnumSerializer<
: public ContiguousEnumSerializerInclusive<
mozilla::layers::ScrollDirection,
mozilla::layers::ScrollDirection::NONE,
mozilla::layers::ScrollDirection::SENTINEL>
mozilla::layers::kHighestScrollDirection>
{};
template<>
struct ParamTraits<mozilla::layers::FrameMetrics::ScrollOffsetUpdateType>
: public ContiguousEnumSerializer<
: public ContiguousEnumSerializerInclusive<
mozilla::layers::FrameMetrics::ScrollOffsetUpdateType,
mozilla::layers::FrameMetrics::ScrollOffsetUpdateType::eNone,
mozilla::layers::FrameMetrics::ScrollOffsetUpdateType::eSentinel>
mozilla::layers::FrameMetrics::sHighestScrollOffsetUpdateType>
{};
template<>
@ -441,10 +441,10 @@ struct ParamTraits<mozilla::layers::FocusTarget::ScrollTargets>
template <>
struct ParamTraits<mozilla::layers::FocusTarget::FocusTargetType>
: public ContiguousEnumSerializer<
: public ContiguousEnumSerializerInclusive<
mozilla::layers::FocusTarget::FocusTargetType,
mozilla::layers::FocusTarget::eNone,
mozilla::layers::FocusTarget::eSentinel>
mozilla::layers::FocusTarget::sHighestFocusTargetType>
{};
template <>
@ -484,10 +484,10 @@ struct ParamTraits<mozilla::layers::FocusTarget>
template <>
struct ParamTraits<mozilla::layers::KeyboardScrollAction::KeyboardScrollActionType>
: public ContiguousEnumSerializer<
: public ContiguousEnumSerializerInclusive<
mozilla::layers::KeyboardScrollAction::KeyboardScrollActionType,
mozilla::layers::KeyboardScrollAction::KeyboardScrollActionType::eScrollCharacter,
mozilla::layers::KeyboardScrollAction::KeyboardScrollActionType::eSentinel>
mozilla::layers::KeyboardScrollAction::sHighestKeyboardScrollActionType>
{};
template <>
@ -557,24 +557,25 @@ struct ParamTraits<mozilla::layers::KeyboardMap>
}
};
typedef mozilla::layers::GeckoContentController::TapType TapType;
typedef mozilla::layers::GeckoContentController GeckoContentController;
typedef GeckoContentController::TapType TapType;
template <>
struct ParamTraits<TapType>
: public ContiguousEnumSerializer<
: public ContiguousEnumSerializerInclusive<
TapType,
TapType::eSingleTap,
TapType::eSentinel>
GeckoContentController::sHighestTapType>
{};
typedef mozilla::layers::GeckoContentController::APZStateChange APZStateChange;
typedef GeckoContentController::APZStateChange APZStateChange;
template <>
struct ParamTraits<APZStateChange>
: public ContiguousEnumSerializer<
: public ContiguousEnumSerializerInclusive<
APZStateChange,
APZStateChange::eTransformBegin,
APZStateChange::eSentinel>
GeckoContentController::sHighestAPZStateChange>
{};
template<>

View File

@ -7,6 +7,7 @@
#define ROUNDED_RECT_H
#include "gfxRect.h"
#include "gfxTypes.h"
#include "mozilla/gfx/PathHelpers.h"
namespace mozilla {

View File

@ -10,6 +10,7 @@
#include "mozilla/UniquePtr.h"
#include "gfxPoint.h"
#include "gfxRect.h"
#include "gfxTypes.h"
#include "nscore.h"
#include "nsSize.h"
@ -18,7 +19,6 @@
#include "nsStringFwd.h"
class gfxImageSurface;
struct gfxRect;
template <typename T>
struct already_AddRefed;

View File

@ -7,13 +7,13 @@
#define GFX_BLUR_H
#include "gfxTypes.h"
#include "gfxRect.h"
#include "nsSize.h"
#include "gfxPoint.h"
#include "mozilla/RefPtr.h"
#include "mozilla/gfx/Blur.h"
class gfxContext;
struct gfxRect;
namespace mozilla {
namespace gfx {

View File

@ -232,8 +232,7 @@ gfxContext::Rectangle(const gfxRect& rect, bool snapToPixels)
gfxMatrix mat = ThebesMatrix(mTransform);
if (mat.Invert()) {
// We need the user space rect.
newRect.TransformBoundsBy(mat);
rec = ToRect(newRect);
rec = ToRect(mat.TransformBounds(newRect));
} else {
rec = Rect();
}

View File

@ -8,8 +8,10 @@
#include "gfxRect.h"
#include "gfxMatrix.h"
#include "gfxTypes.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/gfx/Types.h"
#include "nsISupportsImpl.h"
class gfxContext;
class gfxPattern;

View File

@ -7,13 +7,13 @@
#define GFX_GLYPHEXTENTS_H
#include "gfxFont.h"
#include "gfxRect.h"
#include "nsTHashtable.h"
#include "nsHashKeys.h"
#include "nsTArray.h"
#include "mozilla/MemoryReporting.h"
class gfxContext;
struct gfxRect;
namespace mozilla {
namespace gfx {

View File

@ -1,109 +0,0 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* 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 "gfxRect.h"
#include "nsMathUtils.h"
#include "mozilla/gfx/Matrix.h"
#include "gfxQuad.h"
gfxQuad
gfxRect::TransformToQuad(const mozilla::gfx::Matrix4x4 &aMatrix) const
{
gfxPoint points[4];
points[0] = aMatrix.TransformPoint(TopLeft());
points[1] = aMatrix.TransformPoint(TopRight());
points[2] = aMatrix.TransformPoint(BottomRight());
points[3] = aMatrix.TransformPoint(BottomLeft());
// Could this ever result in lines that intersect? I don't think so.
return gfxQuad(points[0], points[1], points[2], points[3]);
}
void
gfxRect::TransformBy(const mozilla::gfx::MatrixDouble& aMatrix)
{
*this = gfxRect(aMatrix.TransformPoint(TopLeft()),
aMatrix.TransformSize(Size()));
}
void
gfxRect::TransformBoundsBy(const mozilla::gfx::MatrixDouble& aMatrix)
{
RectDouble tmp(x, y, width, height);
tmp = aMatrix.TransformBounds(tmp);
x = tmp.x;
y = tmp.y;
width = tmp.width;
height = tmp.height;
}
static bool
WithinEpsilonOfInteger(gfxFloat aX, gfxFloat aEpsilon)
{
return fabs(NS_round(aX) - aX) <= fabs(aEpsilon);
}
bool
gfxRect::WithinEpsilonOfIntegerPixels(gfxFloat aEpsilon) const
{
NS_ASSERTION(-0.5 < aEpsilon && aEpsilon < 0.5, "Nonsense epsilon value");
return (WithinEpsilonOfInteger(x, aEpsilon) &&
WithinEpsilonOfInteger(y, aEpsilon) &&
WithinEpsilonOfInteger(width, aEpsilon) &&
WithinEpsilonOfInteger(height, aEpsilon));
}
/* Clamp r to CAIRO_COORD_MIN .. CAIRO_COORD_MAX
* these are to be device coordinates.
*
* Cairo is currently using 24.8 fixed point,
* so -2^24 .. 2^24-1 is our valid
*/
#define CAIRO_COORD_MAX (16777215.0)
#define CAIRO_COORD_MIN (-16777216.0)
void
gfxRect::Condition()
{
// if either x or y is way out of bounds;
// note that we don't handle negative w/h here
if (x > CAIRO_COORD_MAX) {
x = CAIRO_COORD_MAX;
width = 0.0;
}
if (y > CAIRO_COORD_MAX) {
y = CAIRO_COORD_MAX;
height = 0.0;
}
if (x < CAIRO_COORD_MIN) {
width += x - CAIRO_COORD_MIN;
if (width < 0.0)
width = 0.0;
x = CAIRO_COORD_MIN;
}
if (y < CAIRO_COORD_MIN) {
height += y - CAIRO_COORD_MIN;
if (height < 0.0)
height = 0.0;
y = CAIRO_COORD_MIN;
}
if (x + width > CAIRO_COORD_MAX) {
width = CAIRO_COORD_MAX - x;
}
if (y + height > CAIRO_COORD_MAX) {
height = CAIRO_COORD_MAX - y;
}
}

View File

@ -6,109 +6,9 @@
#ifndef GFX_RECT_H
#define GFX_RECT_H
#include "gfxTypes.h"
#include "gfxPoint.h"
#include "nsDebug.h"
#include "nsRect.h"
#include "mozilla/gfx/BaseMargin.h"
#include "mozilla/gfx/BaseRect.h"
#include "mozilla/gfx/MatrixFwd.h"
#include "mozilla/gfx/Rect.h"
#include "mozilla/Assertions.h"
struct gfxQuad;
typedef mozilla::gfx::MarginDouble gfxMargin;
struct gfxRect :
public mozilla::gfx::BaseRect<gfxFloat, gfxRect, gfxPoint, gfxSize, gfxMargin> {
typedef mozilla::gfx::BaseRect<gfxFloat, gfxRect, gfxPoint, gfxSize, gfxMargin> Super;
gfxRect() : Super() {}
gfxRect(const gfxPoint& aPos, const gfxSize& aSize) :
Super(aPos, aSize) {}
gfxRect(gfxFloat aX, gfxFloat aY, gfxFloat aWidth, gfxFloat aHeight) :
Super(aX, aY, aWidth, aHeight) {}
/**
* Return true if all components of this rect are within
* aEpsilon of integer coordinates, defined as
* |round(coord) - coord| <= |aEpsilon|
* for x,y,width,height.
*/
bool WithinEpsilonOfIntegerPixels(gfxFloat aEpsilon) const;
gfxPoint AtCorner(mozilla::Corner corner) const {
switch (corner) {
case mozilla::eCornerTopLeft: return TopLeft();
case mozilla::eCornerTopRight: return TopRight();
case mozilla::eCornerBottomRight: return BottomRight();
case mozilla::eCornerBottomLeft: return BottomLeft();
}
return gfxPoint(0.0, 0.0);
}
gfxPoint CCWCorner(mozilla::Side side) const {
switch (side) {
case mozilla::eSideTop: return TopLeft();
case mozilla::eSideRight: return TopRight();
case mozilla::eSideBottom: return BottomRight();
case mozilla::eSideLeft: return BottomLeft();
}
MOZ_CRASH("Incomplete switch");
}
gfxPoint CWCorner(mozilla::Side side) const {
switch (side) {
case mozilla::eSideTop: return TopRight();
case mozilla::eSideRight: return BottomRight();
case mozilla::eSideBottom: return BottomLeft();
case mozilla::eSideLeft: return TopLeft();
}
MOZ_CRASH("Incomplete switch");
}
/* Conditions this border to Cairo's max coordinate space.
* The caller can check IsEmpty() after Condition() -- if it's TRUE,
* the caller can possibly avoid doing any extra rendering.
*/
void Condition();
void Scale(gfxFloat k) {
NS_ASSERTION(k >= 0.0, "Invalid (negative) scale factor");
x *= k;
y *= k;
width *= k;
height *= k;
}
void Scale(gfxFloat sx, gfxFloat sy) {
NS_ASSERTION(sx >= 0.0, "Invalid (negative) scale factor");
NS_ASSERTION(sy >= 0.0, "Invalid (negative) scale factor");
x *= sx;
y *= sy;
width *= sx;
height *= sy;
}
void ScaleInverse(gfxFloat k) {
NS_ASSERTION(k > 0.0, "Invalid (negative) scale factor");
x /= k;
y /= k;
width /= k;
height /= k;
}
/*
* Transform this rectangle with aMatrix, resulting in a gfxQuad.
*/
gfxQuad TransformToQuad(const mozilla::gfx::Matrix4x4 &aMatrix) const;
// Some temporary functions that we need until gfxRect gets turned into a
// typedef for RectDouble. It would be simpler to put these in Matrix.h
// but that code shouldn't #include gfxRect.h so we put it here instead.
void TransformBy(const mozilla::gfx::MatrixDouble& aMatrix);
void TransformBoundsBy(const mozilla::gfx::MatrixDouble& aMatrix);
};
typedef mozilla::gfx::RectDouble gfxRect;
#endif /* GFX_RECT_H */

View File

@ -11,6 +11,7 @@
#include "gfxImageSurface.h"
#include "gfxPlatform.h"
#include "gfxDrawable.h"
#include "gfxQuad.h"
#include "imgIEncoder.h"
#include "mozilla/Base64.h"
#include "mozilla/dom/ImageEncoder.h"
@ -751,6 +752,71 @@ gfxUtils::GfxRectToIntRect(const gfxRect& aIn, IntRect* aOut)
return gfxRect(aOut->x, aOut->y, aOut->width, aOut->height).IsEqualEdges(aIn);
}
/* Clamp r to CAIRO_COORD_MIN .. CAIRO_COORD_MAX
* these are to be device coordinates.
*
* Cairo is currently using 24.8 fixed point,
* so -2^24 .. 2^24-1 is our valid
*/
/*static*/ void
gfxUtils::ConditionRect(gfxRect& aRect)
{
#define CAIRO_COORD_MAX (16777215.0)
#define CAIRO_COORD_MIN (-16777216.0)
// if either x or y is way out of bounds;
// note that we don't handle negative w/h here
if (aRect.x > CAIRO_COORD_MAX) {
aRect.x = CAIRO_COORD_MAX;
aRect.width = 0.0;
}
if (aRect.y > CAIRO_COORD_MAX) {
aRect.y = CAIRO_COORD_MAX;
aRect.height = 0.0;
}
if (aRect.x < CAIRO_COORD_MIN) {
aRect.width += aRect.x - CAIRO_COORD_MIN;
if (aRect.width < 0.0) {
aRect.width = 0.0;
}
aRect.x = CAIRO_COORD_MIN;
}
if (aRect.y < CAIRO_COORD_MIN) {
aRect.height += aRect.y - CAIRO_COORD_MIN;
if (aRect.height < 0.0) {
aRect.height = 0.0;
}
aRect.y = CAIRO_COORD_MIN;
}
if (aRect.x + aRect.width > CAIRO_COORD_MAX) {
aRect.width = CAIRO_COORD_MAX - aRect.x;
}
if (aRect.y + aRect.height > CAIRO_COORD_MAX) {
aRect.height = CAIRO_COORD_MAX - aRect.y;
}
#undef CAIRO_COORD_MAX
#undef CAIRO_COORD_MIN
}
/*static*/ gfxQuad
gfxUtils::TransformToQuad(const gfxRect& aRect,
const mozilla::gfx::Matrix4x4 &aMatrix)
{
gfxPoint points[4];
points[0] = aMatrix.TransformPoint(aRect.TopLeft());
points[1] = aMatrix.TransformPoint(aRect.TopRight());
points[2] = aMatrix.TransformPoint(aRect.BottomRight());
points[3] = aMatrix.TransformPoint(aRect.BottomLeft());
// Could this ever result in lines that intersect? I don't think so.
return gfxQuad(points[0], points[1], points[2], points[3]);
}
/* static */ void gfxUtils::ClearThebesSurface(gfxASurface* aSurface)
{
if (aSurface->CairoStatus()) {

View File

@ -21,6 +21,7 @@
class gfxASurface;
class gfxDrawable;
struct gfxQuad;
class nsIInputStream;
class nsIGfxInfo;
class nsIPresShell;
@ -131,6 +132,18 @@ public:
*/
static bool GfxRectToIntRect(const gfxRect& aIn, mozilla::gfx::IntRect* aOut);
/* Conditions this border to Cairo's max coordinate space.
* The caller can check IsEmpty() after Condition() -- if it's TRUE,
* the caller can possibly avoid doing any extra rendering.
*/
static void ConditionRect(gfxRect& aRect);
/*
* Transform this rectangle with aMatrix, resulting in a gfxQuad.
*/
static gfxQuad TransformToQuad(const gfxRect& aRect,
const mozilla::gfx::Matrix4x4& aMatrix);
/**
* Return the smallest power of kScaleResolution (2) greater than or equal to
* aVal.

View File

@ -200,7 +200,6 @@ UNIFIED_SOURCES += [
'gfxMathTable.cpp',
'gfxPattern.cpp',
'gfxPlatformFontList.cpp',
'gfxRect.cpp',
'gfxScriptItemizer.cpp',
'gfxSkipChars.cpp',
'gfxSVGGlyphs.cpp',

View File

@ -110,17 +110,17 @@ public:
void TransformBy(const gfxMatrix& aMatrix)
{
mRect.TransformBy(aMatrix);
mRect = aMatrix.TransformRect(mRect);
if (mIsRestricted) {
mRestriction.TransformBy(aMatrix);
mRestriction = aMatrix.TransformRect(mRestriction);
}
}
void TransformBoundsBy(const gfxMatrix& aMatrix)
{
mRect.TransformBoundsBy(aMatrix);
mRect = aMatrix.TransformBounds(mRect);
if (mIsRestricted) {
mRestriction.TransformBoundsBy(aMatrix);
mRestriction = aMatrix.TransformBounds(mRestriction);
}
}

View File

@ -364,8 +364,8 @@ OrientedImage::GetImageSpaceInvalidationRect(const nsIntRect& aRect)
// Transform the invalidation rect into the correct orientation.
gfxMatrix matrix(OrientationMatrix(innerSize));
gfxRect invalidRect(rect.x, rect.y, rect.width, rect.height);
invalidRect.TransformBoundsBy(matrix);
gfxRect invalidRect(matrix.TransformBounds(gfxRect(rect.x, rect.y,
rect.width, rect.height)));
return IntRect::RoundOut(invalidRect.x, invalidRect.y,
invalidRect.width, invalidRect.height);

View File

@ -162,6 +162,24 @@ public:
}
};
template <typename E,
E MinLegal,
E MaxLegal>
class ContiguousEnumValidatorInclusive
{
// Silence overzealous -Wtype-limits bug in GCC fixed in GCC 4.8:
// "comparison of unsigned expression >= 0 is always true"
// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11856
template <typename T>
static bool IsLessThanOrEqual(T a, T b) { return a <= b; }
public:
static bool IsLegalValue(E e)
{
return IsLessThanOrEqual(MinLegal, e) && e <= MaxLegal;
}
};
template <typename E,
E AllBits>
struct BitFlagsEnumValidator
@ -196,6 +214,20 @@ struct ContiguousEnumSerializer
ContiguousEnumValidator<E, MinLegal, HighBound>>
{};
/**
* This is similar to ContiguousEnumSerializer, but the last template
* parameter is expected to be the highest legal value, rather than a
* sentinel value. This is intended to support enumerations that don't
* have sentinel values.
*/
template <typename E,
E MinLegal,
E MaxLegal>
struct ContiguousEnumSerializerInclusive
: EnumSerializer<E,
ContiguousEnumValidatorInclusive<E, MinLegal, MaxLegal>>
{};
/**
* Specialization of EnumSerializer for enums representing bit flags.
*

View File

@ -6587,19 +6587,15 @@ ComputeSnappedImageDrawingParameters(gfxContext* aCtx,
if (didSnap && !invTransform.HasNonIntegerTranslation()) {
// This form of Transform is safe to call since non-axis-aligned
// transforms wouldn't be snapped.
devPixelDirty.TransformBy(currentMatrix);
devPixelDirty = currentMatrix.TransformRect(devPixelDirty);
devPixelDirty.RoundOut();
fill = fill.Intersect(devPixelDirty);
}
if (fill.IsEmpty())
return SnappedImageDrawingParameters();
gfxRect imageSpaceFill = fill;
if (didSnap) {
imageSpaceFill.TransformBy(invTransform);
} else {
imageSpaceFill.TransformBoundsBy(invTransform);
}
gfxRect imageSpaceFill(didSnap ? invTransform.TransformRect(fill)
: invTransform.TransformBounds(fill));
// If we didn't snap, we need to post-multiply the matrix on the context to
// get the final matrix we'll draw with, because we didn't take it into

View File

@ -29,7 +29,7 @@
#include "nsCycleCollectionParticipant.h"
#include "nsChangeHint.h"
#include <algorithm>
// This also pulls in gfxTypes.h, which we cannot include directly.
#include "gfxTypes.h"
#include "gfxRect.h"
#include "nsTArray.h"
#include "nsAutoPtr.h"

View File

@ -99,7 +99,7 @@ inDOMUtils::GetAllStyleSheets(nsIDOMDocument *aDocument, uint32_t *aLength,
}
AutoTArray<StyleSheet*, 32> xblSheetArray;
styleSet->AsGecko()->AppendAllXBLStyleSheets(xblSheetArray);
styleSet->AppendAllXBLStyleSheets(xblSheetArray);
// The XBL stylesheet array will quite often be full of duplicates. Cope:
nsTHashtable<nsPtrHashKey<StyleSheet>> sheetSet;

View File

@ -2334,7 +2334,7 @@ SetupImageLayerClip(nsCSSRendering::ImageLayerClipState& aClipState,
gfxRect bgAreaGfx = nsLayoutUtils::RectToGfxRect(
aClipState.mAdditionalBGClipArea, aAppUnitsPerPixel);
bgAreaGfx.Round();
bgAreaGfx.Condition();
gfxUtils::ConditionRect(bgAreaGfx);
aAutoSR->EnsureSaved(aCtx);
aCtx->NewPath();
@ -2408,7 +2408,7 @@ DrawBackgroundColor(nsCSSRendering::ImageLayerClipState& aClipState,
gfxRect bgAdditionalAreaGfx = nsLayoutUtils::RectToGfxRect(
aClipState.mAdditionalBGClipArea, aAppUnitsPerPixel);
bgAdditionalAreaGfx.Round();
bgAdditionalAreaGfx.Condition();
gfxUtils::ConditionRect(bgAdditionalAreaGfx);
aCtx->NewPath();
aCtx->Rectangle(bgAdditionalAreaGfx, true);
aCtx->Clip();
@ -4287,15 +4287,14 @@ nsContextBoxBlur::Init(const nsRect& aRect, nscoord aSpreadRadius,
dirtyRect.RoundOut();
gfxMatrix transform = aDestinationCtx->CurrentMatrix();
rect.TransformBoundsBy(transform);
rect = transform.TransformBounds(rect);
mPreTransformed = !transform.IsIdentity();
// Create the temporary surface for blurring
dirtyRect.TransformBoundsBy(transform);
dirtyRect = transform.TransformBounds(dirtyRect);
if (aSkipRect) {
gfxRect skipRect = *aSkipRect;
skipRect.TransformBoundsBy(transform);
gfxRect skipRect = transform.TransformBounds(*aSkipRect);
mContext = mAlphaBoxBlur.Init(aDestinationCtx, rect, spreadRadius,
blurRadius, &dirtyRect, &skipRect);
} else {
@ -4398,11 +4397,9 @@ nsContextBoxBlur::BlurRectangle(gfxContext* aDestinationCtx,
nsLayoutUtils::RectToGfxRect(aDirtyRect, aAppUnitsPerDevPixel);
dirtyRect.RoundOut();
gfxRect shadowThebesRect = ThebesRect(shadowGfxRect);
shadowThebesRect.TransformBoundsBy(transform);
dirtyRect.TransformBoundsBy(transform);
gfxRect skipRect = aSkipRect;
skipRect.TransformBoundsBy(transform);
gfxRect shadowThebesRect = transform.TransformBounds(ThebesRect(shadowGfxRect));
dirtyRect = transform.TransformBounds(dirtyRect);
gfxRect skipRect = transform.TransformBounds(aSkipRect);
if (aCornerRadii) {
aCornerRadii->Scale(scaleX, scaleY);

View File

@ -3343,13 +3343,13 @@ nsCSSBorderRenderer::DrawBorders()
// rect is supposed to enclose the entire border
{
gfxRect outerRect = ThebesRect(mOuterRect);
outerRect.Condition();
gfxUtils::ConditionRect(outerRect);
if (outerRect.IsEmpty())
return;
mOuterRect = ToRect(outerRect);
gfxRect innerRect = ThebesRect(mInnerRect);
innerRect.Condition();
gfxUtils::ConditionRect(innerRect);
mInnerRect = ToRect(innerRect);
}

View File

@ -12,7 +12,7 @@ default-preferences pref(layout.css.prefixes.webkit,true)
== webkit-gradient-linear-1b.html webkit-gradient-linear-1-ref.html
== webkit-gradient-linear-1c.html webkit-gradient-linear-1-ref.html
== webkit-gradient-linear-1d.html webkit-gradient-linear-1-ref.html
fails-if(styloVsGecko||stylo) == webkit-gradient-linear-2.html webkit-gradient-linear-2-ref.html
== webkit-gradient-linear-2.html webkit-gradient-linear-2-ref.html
# Tests for -webkit-gradient(radial, ...)
== webkit-gradient-radial-1a.html webkit-gradient-radial-1-ref.html

View File

@ -7,6 +7,8 @@
#ifndef mozilla_css_SheetParsingMode_h
#define mozilla_css_SheetParsingMode_h
#include <stdint.h>
namespace mozilla {
namespace css {
@ -40,7 +42,7 @@ namespace css {
* Servo backend to recognize the sheets as the agent level, but Gecko
* backend will parse it under _author_ level.
*/
enum SheetParsingMode {
enum SheetParsingMode : uint8_t {
eAuthorSheetFeatures = 0,
eUserSheetFeatures,
eAgentSheetFeatures,

View File

@ -8,6 +8,7 @@
#ifndef mozilla_StyleAnimationValue_h_
#define mozilla_StyleAnimationValue_h_
#include "gfxPoint.h"
#include "mozilla/gfx/MatrixFwd.h"
#include "mozilla/ServoBindingTypes.h"
#include "mozilla/UniquePtr.h"

View File

@ -28,9 +28,9 @@ StyleSheet::StyleSheet(StyleBackendType aType, css::SheetParsingMode aParsingMod
, mParsingMode(aParsingMode)
, mType(aType)
, mDisabled(false)
, mDirty(false)
, mDocumentAssociationMode(NotOwnedByDocument)
, mInner(nullptr)
, mDirty(false)
{
}
@ -47,11 +47,11 @@ StyleSheet::StyleSheet(const StyleSheet& aCopy,
, mParsingMode(aCopy.mParsingMode)
, mType(aCopy.mType)
, mDisabled(aCopy.mDisabled)
, mDirty(aCopy.mDirty)
// We only use this constructor during cloning. It's the cloner's
// responsibility to notify us if we end up being owned by a document.
, mDocumentAssociationMode(NotOwnedByDocument)
, mInner(aCopy.mInner) // Shallow copy, but concrete subclasses will fix up.
, mDirty(aCopy.mDirty)
{
MOZ_ASSERT(mInner, "Should only copy StyleSheets with an mInner.");
mInner->AddSheet(this);

View File

@ -144,7 +144,7 @@ public:
void AppendAllChildSheets(nsTArray<StyleSheet*>& aArray);
// style sheet owner info
enum DocumentAssociationMode {
enum DocumentAssociationMode : uint8_t {
// OwnedByDocument means mDocument owns us (possibly via a chain of other
// stylesheets).
OwnedByDocument,
@ -337,6 +337,8 @@ protected:
const StyleBackendType mType;
bool mDisabled;
bool mDirty; // has been modified
// mDocumentAssociationMode determines whether mDocument directly owns us (in
// the sense that if it's known-live then we're known-live). Always
// NotOwnedByDocument when mDocument is null.
@ -346,8 +348,6 @@ protected:
// StyleSheet clones.
StyleSheetInfo* mInner;
bool mDirty; // has been modified
nsTArray<StyleSetHandle> mStyleSets;
friend class ::nsCSSRuleProcessor;

View File

@ -0,0 +1,10 @@
<!doctype html>
<style>
div {
animation: t 1s;
}
@keyframes t {
to { stroke-dasharray: none; }
}
</style>
<div></div>

View File

@ -174,4 +174,5 @@ load 1370793-1.xhtml
load content-only-on-link-before.html
load content-only-on-visited-before.html
load 1375812-1.html
load 1377053-1.html
load 1377256-1.html

View File

@ -1346,13 +1346,6 @@ protected:
// True when the unitless length quirk applies.
bool mUnitlessLengthQuirk : 1;
// Controls access to nonstandard style constructs that are not safe
// for use on the public Web but necessary in UA sheets and/or
// useful in user sheets. The only values stored in this field are
// 0, 1, and 2; three bits are allocated to avoid issues should the
// enum type be signed.
css::SheetParsingMode mParsingMode : 3;
// True if we are in parsing rules for the chrome.
bool mIsChrome : 1;
@ -1390,6 +1383,11 @@ protected:
// out of the parser.
bool mSheetPrincipalRequired;
// Controls access to nonstandard style constructs that are not safe
// for use on the public Web but necessary in UA sheets and/or
// useful in user sheets.
css::SheetParsingMode mParsingMode;
// This enum helps us track whether we've unprefixed "display: -webkit-box"
// (treating it as "display: flex") in an earlier declaration within a series
// of declarations. (This only impacts behavior if
@ -1480,7 +1478,6 @@ CSSParserImpl::CSSParserImpl()
mNavQuirkMode(false),
mHashlessColorQuirk(false),
mUnitlessLengthQuirk(false),
mParsingMode(css::eAuthorSheetFeatures),
mIsChrome(false),
mIsSVGMode(false),
mViewportUnitsEnabled(true),
@ -1489,6 +1486,7 @@ CSSParserImpl::CSSParserImpl()
mInFailingSupportsRule(false),
mSuppressErrors(false),
mSheetPrincipalRequired(true),
mParsingMode(css::eAuthorSheetFeatures),
mWebkitBoxUnprefixState(eNotParsingDecls),
mNextFree(nullptr)
{

View File

@ -10,9 +10,11 @@
#ifndef nsStyleTransformMatrix_h_
#define nsStyleTransformMatrix_h_
#include "gfxPoint.h"
#include "mozilla/gfx/Matrix.h"
#include "mozilla/EnumeratedArray.h"
#include "nsCSSValue.h"
#include "nsSize.h"
#include <limits>

View File

@ -999,9 +999,7 @@ TextRenderedRun::GetFrameUserSpaceRect(nsPresContext* aContext,
return r;
}
gfxMatrix m = GetTransformFromRunUserSpaceToFrameUserSpace(aContext);
gfxRect thebesRect = r.ToThebesRect();
thebesRect.TransformBoundsBy(m);
return thebesRect;
return m.TransformBounds(r.ToThebesRect());
}
SVGBBox
@ -1017,9 +1015,7 @@ TextRenderedRun::GetUserSpaceRect(nsPresContext* aContext,
if (aAdditionalTransform) {
m *= *aAdditionalTransform;
}
gfxRect thebesRect = r.ToThebesRect();
thebesRect.TransformBoundsBy(m);
return thebesRect;
return m.TransformBounds(r.ToThebesRect());
}
void
@ -3628,8 +3624,8 @@ SVGTextFrame::PaintSVG(gfxContext& aContext,
mRect.width / appUnitsPerDevPixel,
mRect.height / appUnitsPerDevPixel);
frameRect.TransformBoundsBy(GetCanvasTM());
nsRect canvasRect = nsLayoutUtils::RoundGfxRectToAppRect(frameRect, 1);
nsRect canvasRect = nsLayoutUtils::RoundGfxRectToAppRect(
GetCanvasTM().TransformBounds(frameRect), 1);
if (!canvasRect.Intersects(dirtyRect)) {
return;
}
@ -4301,8 +4297,7 @@ SVGTextFrame::GetExtentOfChar(nsIContent* aContent,
}
// Transform the glyph's rect into user space.
glyphRect.TransformBoundsBy(m);
gfxRect r = glyphRect;
gfxRect r = m.TransformBounds(glyphRect);
NS_ADDREF(*aResult = new dom::SVGRect(aContent, r.x, r.y, r.width, r.height));
return NS_OK;
@ -5570,8 +5565,7 @@ SVGTextFrame::TransformFrameRectFromTextChild(const nsRect& aRect,
// account the font size scale.
gfxMatrix m = run.GetTransformFromRunUserSpaceToUserSpace(presContext);
m.PreScale(mFontSizeScaleFactor, mFontSizeScaleFactor);
gfxRect rectInUserSpace = rectInFrameUserSpace;
rectInUserSpace.TransformBy(m);
gfxRect rectInUserSpace = m.TransformRect(rectInFrameUserSpace);
// Union it into the result.
result.UnionRect(result, rectInUserSpace);

View File

@ -558,8 +558,8 @@ nsFilterInstance::FrameSpaceToFilterSpace(const nsRect* aRect) const
}
gfxRect rectInCSSPx =
nsLayoutUtils::RectToGfxRect(*aRect, nsPresContext::AppUnitsPerCSSPixel());
gfxRect rectInFilterSpace = rectInCSSPx;
rectInFilterSpace.TransformBoundsBy(mFrameSpaceInCSSPxToFilterSpaceTransform);
gfxRect rectInFilterSpace =
mFrameSpaceInCSSPxToFilterSpaceTransform.TransformBounds(rectInCSSPx);
rectInFilterSpace.RoundOut();
nsIntRect intRect;
if (gfxUtils::GfxRectToIntRect(rectInFilterSpace, &intRect)) {
@ -576,7 +576,7 @@ nsFilterInstance::FilterSpaceToFrameSpace(const nsIntRect& aRect) const
return nsRect();
}
gfxRect r(aRect.x, aRect.y, aRect.width, aRect.height);
r.TransformBoundsBy(mFilterSpaceToFrameSpaceInCSSPxTransform);
r = mFilterSpaceToFrameSpaceInCSSPxTransform.TransformBounds(r);
// nsLayoutUtils::RoundGfxRectToAppRect rounds out.
return nsLayoutUtils::RoundGfxRectToAppRect(r, nsPresContext::AppUnitsPerCSSPixel());
}

View File

@ -234,7 +234,7 @@ nsSVGForeignObjectFrame::PaintSVG(gfxContext& aContext,
gfxRect transDirtyRect = gfxRect(aDirtyRect->x, aDirtyRect->y,
aDirtyRect->width, aDirtyRect->height);
transDirtyRect.TransformBoundsBy(invmatrix);
transDirtyRect = invmatrix.TransformBounds(transDirtyRect);
kidDirtyRect.IntersectRect(kidDirtyRect,
nsLayoutUtils::RoundGfxRectToAppRect(transDirtyRect,

View File

@ -8,6 +8,7 @@
#include "mozilla/Attributes.h"
#include "gfxMatrix.h"
#include "gfxRect.h"
#include "nsCOMPtr.h"
#include "nsFrame.h"
#include "nsLiteralString.h"
@ -20,8 +21,6 @@ class nsIFrame;
class nsIPresShell;
class nsStyleContext;
struct gfxRect;
namespace mozilla {
class nsSVGAnimatedTransformList;

View File

@ -1218,7 +1218,7 @@ nsSVGIntegrationUtils::DrawableFromPaintServer(nsIFrame* aFrame,
gfxRect overrideBounds(0, 0,
aPaintServerSize.width, aPaintServerSize.height);
overrideBounds.ScaleInverse(aFrame->PresContext()->AppUnitsPerDevPixel());
overrideBounds.Scale(1.0 / aFrame->PresContext()->AppUnitsPerDevPixel());
imgDrawingParams imgParams(aFlags);
RefPtr<gfxPattern> pattern =
server->GetPaintServerPattern(aTarget, aDrawTarget,

View File

@ -6,6 +6,7 @@
#ifndef __NS_SVGPAINTSERVERFRAME_H__
#define __NS_SVGPAINTSERVERFRAME_H__
#include "gfxRect.h"
#include "mozilla/Attributes.h"
#include "nsCOMPtr.h"
#include "nsFrame.h"
@ -24,8 +25,6 @@ class gfxContext;
class gfxPattern;
class nsStyleContext;
struct gfxRect;
/**
* RAII class used to temporarily set and remove the
* NS_FRAME_DRAWING_AS_PAINTSERVER frame state bit while a frame is being

View File

@ -471,9 +471,8 @@ public:
if (userToDeviceSpace.IsSingular()) {
return;
}
gfxRect dirtyBounds =
gfxRect(aDirtyRect->x, aDirtyRect->y, aDirtyRect->width, aDirtyRect->height);
dirtyBounds.TransformBoundsBy(userToDeviceSpace);
gfxRect dirtyBounds = userToDeviceSpace.TransformBounds(
gfxRect(aDirtyRect->x, aDirtyRect->y, aDirtyRect->width, aDirtyRect->height));
dirtyBounds.RoundOut();
if (gfxUtils::GfxRectToIntRect(dirtyBounds, &tmpDirtyRect)) {
dirtyRect = &tmpDirtyRect;
@ -844,9 +843,9 @@ nsSVGUtils::PaintFrameWithEffects(nsIFrame *aFrame,
}
gfxMatrix deviceToUserSpace = userToDeviceSpace;
deviceToUserSpace.Invert();
gfxRect dirtyBounds = gfxRect(aDirtyRect->x, aDirtyRect->y,
aDirtyRect->width, aDirtyRect->height);
dirtyBounds.TransformBoundsBy(deviceToUserSpace);
gfxRect dirtyBounds = deviceToUserSpace.TransformBounds(
gfxRect(aDirtyRect->x, aDirtyRect->y,
aDirtyRect->width, aDirtyRect->height));
tmpDirtyRegion =
nsLayoutUtils::RoundGfxRectToAppRect(
dirtyBounds, aFrame->PresContext()->AppUnitsPerCSSPixel()) -
@ -969,8 +968,8 @@ nsSVGUtils::TransformFrameRectToOuterSVG(const nsRect& aRect,
{
gfxRect r(aRect.x, aRect.y, aRect.width, aRect.height);
r.Scale(1.0 / nsPresContext::AppUnitsPerCSSPixel());
r.TransformBoundsBy(aMatrix);
return nsLayoutUtils::RoundGfxRectToAppRect(r, aPresContext->AppUnitsPerDevPixel());
return nsLayoutUtils::RoundGfxRectToAppRect(
aMatrix.TransformBounds(r), aPresContext->AppUnitsPerDevPixel());
}
IntSize
@ -1154,7 +1153,7 @@ nsSVGUtils::GetBBox(nsIFrame* aFrame, uint32_t aFlags,
clipRect =
nsSVGUtils::GetClipRectForFrame(aFrame, x, y, width, height);
if (aFrame->IsSVGForeignObjectFrame() || aFrame->IsSVGUseFrame()) {
clipRect.TransformBoundsBy(matrix);
clipRect = matrix.TransformBounds(clipRect);
}
}
nsSVGEffects::EffectProperties effectProperties =
@ -1888,10 +1887,8 @@ nsSVGUtils::ToCanvasBounds(const gfxRect &aUserspaceRect,
const gfxMatrix &aToCanvas,
const nsPresContext *presContext)
{
gfxRect userspaceRect = aUserspaceRect;
userspaceRect.TransformBoundsBy(aToCanvas);
return nsLayoutUtils::RoundGfxRectToAppRect(
userspaceRect,
aToCanvas.TransformBounds(aUserspaceRect),
presContext->AppUnitsPerDevPixel());
}

File diff suppressed because it is too large Load Diff

View File

@ -205,28 +205,28 @@ struct { \
#define rb_first(a_type, a_field, a_tree, r_node) do { \
rbp_first(a_type, a_field, a_tree, (a_tree)->rbt_root, (r_node)); \
if ((r_node) == &(a_tree)->rbt_nil) { \
(r_node) = NULL; \
(r_node) = nullptr; \
} \
} while (0)
#define rb_last(a_type, a_field, a_tree, r_node) do { \
rbp_last(a_type, a_field, a_tree, (a_tree)->rbt_root, r_node); \
if ((r_node) == &(a_tree)->rbt_nil) { \
(r_node) = NULL; \
(r_node) = nullptr; \
} \
} while (0)
#define rb_next(a_type, a_field, a_cmp, a_tree, a_node, r_node) do { \
rbp_next(a_type, a_field, a_cmp, a_tree, (a_node), (r_node)); \
if ((r_node) == &(a_tree)->rbt_nil) { \
(r_node) = NULL; \
(r_node) = nullptr; \
} \
} while (0)
#define rb_prev(a_type, a_field, a_cmp, a_tree, a_node, r_node) do { \
rbp_prev(a_type, a_field, a_cmp, a_tree, (a_node), (r_node)); \
if ((r_node) == &(a_tree)->rbt_nil) { \
(r_node) = NULL; \
(r_node) = nullptr; \
} \
} while (0)
@ -242,7 +242,7 @@ struct { \
} \
} \
if ((r_node) == &(a_tree)->rbt_nil) { \
(r_node) = NULL; \
(r_node) = nullptr; \
} \
} while (0)
@ -252,7 +252,7 @@ struct { \
*/
#define rb_nsearch(a_type, a_field, a_cmp, a_tree, a_key, r_node) do { \
a_type *rbp_ns_t = (a_tree)->rbt_root; \
(r_node) = NULL; \
(r_node) = nullptr; \
while (rbp_ns_t != &(a_tree)->rbt_nil) { \
int rbp_ns_cmp = (a_cmp)((a_key), rbp_ns_t); \
if (rbp_ns_cmp < 0) { \

146
mfbt/DefineEnum.h Normal file
View File

@ -0,0 +1,146 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* Poor man's reflection for enumerations. */
#ifndef mozilla_DefineEnum_h
#define mozilla_DefineEnum_h
#include <stddef.h> // for size_t
#include "mozilla/MacroArgs.h" // for MOZ_ARG_COUNT
#include "mozilla/MacroForEach.h" // for MOZ_FOR_EACH
/**
* MOZ_UNWRAP_ARGS is a helper macro that unwraps a list of comma-separated
* items enclosed in parentheses, to yield just the items.
*
* Usage: |MOZ_UNWRAP_ARGS foo| (note the absence of parentheses in the
* invocation), where |foo| is a parenthesis-enclosed list.
* For exampe if |foo| is |(3, 4, 5)|, then the expansion is just |3, 4, 5|.
*/
#define MOZ_UNWRAP_ARGS(...) __VA_ARGS__
/**
* MOZ_DEFINE_ENUM(aEnumName, aEnumerators) is a macro that allows
* simultaneously defining an enumeration named |aEnumName|, and a constant
* that stores the number of enumerators it has.
*
* The motivation is to allow the enumeration to evolve over time without
* either having to manually keep such a constant up to date, or having to
* add a special "sentinel" enumerator for this purpose. (While adding a
* "sentinel" enumerator is trivial, it causes headaches with "switch"
* statements. We often try to write "switch" statements whose cases exhaust
* the enumerators and don't have a "default" case, so that if a new
* enumerator is added and we forget to handle it in the "switch", the
* compiler points it out. But this means we need to explicitly handle the
* sentinel in every "switch".)
*
* |aEnumerators| is expected to be a comma-separated list of enumerators,
* enclosed in parentheses. The enumerators may NOT have associated
* initializers (an attempt to have one will result in a compiler error).
* This ensures that the enumerator values are in the range [0, N), where N
* is the number of enumerators.
*
* The list of enumerators cannot contain a trailing comma. This is a
* limitation of MOZ_FOR_EACH, which we use in the implementation; if
* MOZ_FOR_EACH supported trailing commas, we could too.
*
* The generated constant has the name "k" + |aEnumName| + "Count", and type
* "size_t". The enumeration and the constant are both defined in the scope
* in which the macro is invoked.
*
* For convenience, a constant of the enumeration type named
* "kHighest" + |aEnumName| is also defined, whose value is the highest
* valid enumerator, assuming the enumerators have contiguous values starting
* from 0.
*
* Invocation of the macro may be followed by a semicolon, if one prefers a
* more declaration-like syntax.
*
* Example invocation:
* MOZ_DEFINE_ENUM(MyEnum, (Foo, Bar, Baz));
*
* This expands to:
* enum MyEnum { Foo, Bar, Baz };
* constexpr size_t kMyEnumCount = 3;
* constexpr MyEnum kHighestMyEnum = MyEnum(kMyEnumCount - 1);
* // some static_asserts to ensure the values are in the range [0, 3)
*
* The macro also has several variants:
*
* - A |_CLASS| variant, which generates an |enum class| instead of
* a plain enum.
*
* - A |_WITH_BASE| variant which generates an enum with a specified
* underlying ("base") type, which is provided as an additional
* argument in second position.
*
* - An |_AT_CLASS_SCOPE| variant, designed for enumerations defined
* at class scope. For these, the generated constants are static,
* and have names prefixed with "s" instead of "k" as per
* naming convention.
*
* (and combinations of these).
*/
/*
* A helper macro for asserting that an enumerator does not have an initializer.
*
* The static_assert and the comparison to 0 are just scaffolding; the
* important part is forming the expression |aEnumName::aEnumeratorDecl|.
*
* If |aEnumeratorDecl| is just the enumerator name without an identifier,
* this expression compiles fine. However, if |aEnumeratorDecl| includes an
* initializer, as in |eEnumerator = initializer|, then this will fail to
* compile in expression context, since |eEnumerator| is not an lvalue.
*
* (The static_assert itself should always pass in the absence of the above
* error, since you can't get a negative enumerator value without having
* an initializer somewhere. It just provides a place to put the expression
* we want to form.)
*/
#define MOZ_ASSERT_ENUMERATOR_HAS_NO_INITIALIZER(aEnumName, aEnumeratorDecl) \
static_assert((aEnumName::aEnumeratorDecl) >= aEnumName(0), \
"MOZ_DEFINE_ENUM does not allow enumerators to have initializers");
#define MOZ_DEFINE_ENUM_IMPL(aEnumName, aClassSpec, aBaseSpec, aEnumerators) \
enum aClassSpec aEnumName aBaseSpec { MOZ_UNWRAP_ARGS aEnumerators }; \
constexpr size_t k##aEnumName##Count = MOZ_ARG_COUNT aEnumerators; \
constexpr aEnumName k##Highest##aEnumName = aEnumName(k##aEnumName##Count - 1); \
MOZ_FOR_EACH(MOZ_ASSERT_ENUMERATOR_HAS_NO_INITIALIZER, (aEnumName,), aEnumerators)
#define MOZ_DEFINE_ENUM(aEnumName, aEnumerators) \
MOZ_DEFINE_ENUM_IMPL(aEnumName, , , aEnumerators)
#define MOZ_DEFINE_ENUM_WITH_BASE(aEnumName, aBaseName, aEnumerators) \
MOZ_DEFINE_ENUM_IMPL(aEnumName, , : aBaseName, aEnumerators)
#define MOZ_DEFINE_ENUM_CLASS(aEnumName, aEnumerators) \
MOZ_DEFINE_ENUM_IMPL(aEnumName, class, , aEnumerators)
#define MOZ_DEFINE_ENUM_CLASS_WITH_BASE(aEnumName, aBaseName, aEnumerators) \
MOZ_DEFINE_ENUM_IMPL(aEnumName, class, : aBaseName, aEnumerators)
#define MOZ_DEFINE_ENUM_AT_CLASS_SCOPE_IMPL(aEnumName, aClassSpec, aBaseSpec, aEnumerators) \
enum aClassSpec aEnumName aBaseSpec { MOZ_UNWRAP_ARGS aEnumerators }; \
constexpr static size_t s##aEnumName##Count = MOZ_ARG_COUNT aEnumerators; \
constexpr static aEnumName s##Highest##aEnumName = aEnumName(s##aEnumName##Count - 1); \
MOZ_FOR_EACH(MOZ_ASSERT_ENUMERATOR_HAS_NO_INITIALIZER, (aEnumName,), aEnumerators)
#define MOZ_DEFINE_ENUM_AT_CLASS_SCOPE(aEnumName, aEnumerators) \
MOZ_DEFINE_ENUM_AT_CLASS_SCOPE_IMPL(aEnumName, , , aEnumerators)
#define MOZ_DEFINE_ENUM_WITH_BASE_AT_CLASS_SCOPE(aEnumName, aBaseName, aEnumerators) \
MOZ_DEFINE_ENUM_AT_CLASS_SCOPE_IMPL(aEnumName, , : aBaseName, aEnumerators)
#define MOZ_DEFINE_ENUM_CLASS_AT_CLASS_SCOPE(aEnumName, aEnumerators) \
MOZ_DEFINE_ENUM_AT_CLASS_SCOPE_IMPL(aEnumName, class, , aEnumerators)
#define MOZ_DEFINE_ENUM_CLASS_WITH_BASE_AT_CLASS_SCOPE(aEnumName, aBaseName, aEnumerators) \
MOZ_DEFINE_ENUM_AT_CLASS_SCOPE_IMPL(aEnumName, class, : aBaseName, aEnumerators)
#endif // mozilla_DefineEnum_h

View File

@ -33,6 +33,7 @@ EXPORTS.mozilla = [
'Compression.h',
'DebugOnly.h',
'decimal/Decimal.h',
'DefineEnum.h',
'double-conversion/source/double-conversion.h',
'double-conversion/source/utils.h',
'DoublyLinkedList.h',

View File

@ -0,0 +1,79 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/DefineEnum.h"
// Sanity test for MOZ_DEFINE_ENUM.
MOZ_DEFINE_ENUM(TestEnum1, (EnumeratorA, EnumeratorB, EnumeratorC));
static_assert(EnumeratorA == 0, "Unexpected enumerator value");
static_assert(EnumeratorB == 1, "Unexpected enumerator value");
static_assert(EnumeratorC == 2, "Unexpected enumerator value");
static_assert(kHighestTestEnum1 == EnumeratorC, "Incorrect highest value");
static_assert(kTestEnum1Count == 3, "Incorrect enumerator count");
// Sanity test for MOZ_DEFINE_ENUM_CLASS.
MOZ_DEFINE_ENUM_CLASS(TestEnum2, (A, B, C));
static_assert(TestEnum2::A == TestEnum2(0), "Unexpected enumerator value");
static_assert(TestEnum2::B == TestEnum2(1), "Unexpected enumerator value");
static_assert(TestEnum2::C == TestEnum2(2), "Unexpected enumerator value");
static_assert(kHighestTestEnum2 == TestEnum2::C, "Incorrect highest value");
static_assert(kTestEnum2Count == 3, "Incorrect enumerator count");
// TODO: Test that the _WITH_BASE variants generate enumerators with the
// correct underlying types. To do this, we need an |UnderlyingType|
// type trait, which needs compiler support (recent versions of
// compilers in the GCC family provide an |__underlying_type| builtin
// for this purpose.
// Sanity test for MOZ_DEFINE_ENUM[_CLASS]_AT_CLASS_SCOPE.
struct TestClass {
MOZ_DEFINE_ENUM_AT_CLASS_SCOPE(
TestEnum3, (
EnumeratorA,
EnumeratorB,
EnumeratorC
));
MOZ_DEFINE_ENUM_CLASS_AT_CLASS_SCOPE(
TestEnum4, (
A,
B,
C
));
static_assert(EnumeratorA == 0, "Unexpected enumerator value");
static_assert(EnumeratorB == 1, "Unexpected enumerator value");
static_assert(EnumeratorC == 2, "Unexpected enumerator value");
static_assert(sHighestTestEnum3 == EnumeratorC, "Incorrect highest value");
static_assert(sTestEnum3Count == 3, "Incorrect enumerator count");
static_assert(TestEnum4::A == TestEnum4(0), "Unexpected enumerator value");
static_assert(TestEnum4::B == TestEnum4(1), "Unexpected enumerator value");
static_assert(TestEnum4::C == TestEnum4(2), "Unexpected enumerator value");
static_assert(sHighestTestEnum4 == TestEnum4::C, "Incorrect highest value");
static_assert(sTestEnum4Count == 3, "Incorrect enumerator count");
};
// Test that MOZ_DEFINE_ENUM doesn't allow giving enumerators initializers.
#ifdef CONFIRM_COMPILATION_ERRORS
MOZ_DEFINE_ENUM_CLASS(EnumWithInitializer1, (A = -1, B, C))
MOZ_DEFINE_ENUM_CLASS(EnumWithInitializer2, (A = 1, B, C))
MOZ_DEFINE_ENUM_CLASS(EnumWithInitializer3, (A, B = 6, C))
#endif
int
main()
{
// Nothing to do here, all tests are static_asserts.
return 0;
}

View File

@ -21,6 +21,7 @@ CppUnitTests([
'TestCheckedInt',
'TestCountPopulation',
'TestCountZeroes',
'TestDefineEnum',
'TestDoublyLinkedList',
'TestEndian',
'TestEnumeratedArray',

View File

@ -27,8 +27,6 @@ import java.util.HashMap;
* somewhere in {@link org.mozilla.gecko.sync.telemetry.TelemetryCollector} and friends.
*/
public class TelemetrySyncPingBuilder extends TelemetryLocalPingBuilder {
private static final int DATA_FORMAT_VERSION = 1;
public TelemetrySyncPingBuilder setStages(@NonNull final Serializable data) {
HashMap<String, TelemetryStageCollector> stages = castSyncData(data);
@ -143,7 +141,7 @@ public class TelemetrySyncPingBuilder extends TelemetryLocalPingBuilder {
@Override
public TelemetryLocalPing build() {
payload.put("version", DATA_FORMAT_VERSION);
payload.put("when", System.currentTimeMillis());
return new TelemetryLocalPing(payload, docID);
}

View File

@ -11,6 +11,7 @@ import android.support.annotation.NonNull;
import org.json.simple.JSONArray;
import org.mozilla.gecko.AppConstants;
import org.mozilla.gecko.Locales;
import org.mozilla.gecko.sync.ExtendedJSONObject;
import org.mozilla.gecko.telemetry.TelemetryOutgoingPing;
import org.mozilla.gecko.telemetry.TelemetryPing;
@ -39,7 +40,8 @@ import java.util.TimeZone;
*/
public class TelemetrySyncPingBundleBuilder extends TelemetryPingBuilder {
private static final String PING_TYPE = "sync";
private static final int PING_VERSION = 4;
private static final int PING_BUNDLE_VERSION = 5; // Bug 1374758
private static final int PING_SYNC_DATA_FORMAT_VERSION = 1; // Bug 1374758
public static final String UPLOAD_REASON_FIRST = "first";
public static final String UPLOAD_REASON_CLOCK_DRIFT = "clockdrift";
@ -71,13 +73,13 @@ public class TelemetrySyncPingBundleBuilder extends TelemetryPingBuilder {
pingCreationDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
payload.put("type", PING_TYPE);
payload.put("version", PING_VERSION);
payload.put("version", PING_BUNDLE_VERSION);
payload.put("id", docID);
payload.put("creationDate", pingCreationDateFormat.format(new Date()));
final ExtendedJSONObject application = new ExtendedJSONObject();
application.put("architecture", Build.CPU_ABI);
application.put("buildID", AppConstants.MOZ_APP_BUILDID);
application.put("buildId", AppConstants.MOZ_APP_BUILDID);
application.put("platformVersion", AppConstants.MOZ_APP_VERSION);
application.put("name", AppConstants.MOZ_APP_BASENAME);
application.put("version", AppConstants.MOZ_APP_VERSION);
@ -86,7 +88,17 @@ public class TelemetrySyncPingBundleBuilder extends TelemetryPingBuilder {
application.put("xpcomAbi", AppConstants.MOZ_APP_ABI);
application.put("channel", AppConstants.MOZ_UPDATE_CHANNEL);
// Limited environment object, to help identify platforms easier. See Bug 1374758.
final ExtendedJSONObject os = new ExtendedJSONObject();
os.put("name", "Android");
os.put("version", Integer.toString(Build.VERSION.SDK_INT));
os.put("locale", Locales.getLanguageTag(Locale.getDefault()));
payload.put("application", application);
payload.put("os", os);
pingData.put("version", PING_SYNC_DATA_FORMAT_VERSION);
payload.put("payload", pingData);
return super.build();
}

View File

@ -25,6 +25,7 @@
#include "nsIFileStreams.h"
#include "nsIFileURL.h"
#include "nsIJARChannel.h"
#include "nsIMIMEService.h"
#include "nsIURL.h"
#include "nsIChannel.h"
#include "nsIInputStreamPump.h"
@ -42,6 +43,10 @@
#include "nsILocalFileWin.h"
#endif
#if !defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
#include "mozilla/SandboxSettings.h"
#endif
#define EXTENSION_SCHEME "moz-extension"
using mozilla::ipc::FileDescriptor;
using OptionalIPCStream = mozilla::ipc::OptionalIPCStream;
@ -343,6 +348,9 @@ ExtensionProtocolHandler::GetSingleton()
ExtensionProtocolHandler::ExtensionProtocolHandler()
: SubstitutingProtocolHandler(EXTENSION_SCHEME)
#if !defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
, mAlreadyCheckedDevRepo(false)
#endif
{
mUseRemoteFileChannels = IsNeckoChild() &&
Preferences::GetBool("extensions.webextensions.protocol.remote");
@ -497,6 +505,39 @@ ExtensionProtocolHandler::SubstituteChannel(nsIURI* aURI,
return NS_OK;
}
#if !defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
// The |aRequestedFile| argument must already be Normalize()'d
Result<Ok, nsresult>
ExtensionProtocolHandler::DevRepoContains(nsIFile* aRequestedFile,
bool *aResult)
{
MOZ_ASSERT(!IsNeckoChild());
MOZ_ASSERT(aResult);
*aResult = false;
// On the first invocation, set mDevRepo if this is a
// development build with MOZ_DEVELOPER_REPO_DIR set.
if (!mAlreadyCheckedDevRepo) {
mAlreadyCheckedDevRepo = true;
if (mozilla::IsDevelopmentBuild()) {
char *developer_repo_dir = PR_GetEnv("MOZ_DEVELOPER_REPO_DIR");
if (developer_repo_dir) {
NS_TRY(NS_NewLocalFile(NS_ConvertUTF8toUTF16(developer_repo_dir),
false, getter_AddRefs(mDevRepo)));
NS_TRY(mDevRepo->Normalize());
}
}
}
if (mDevRepo) {
// This is a development build
NS_TRY(mDevRepo->Contains(aRequestedFile, aResult));
}
return Ok();
}
#endif /* !defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX) */
Result<nsCOMPtr<nsIInputStream>, nsresult>
ExtensionProtocolHandler::NewStream(nsIURI* aChildURI,
nsILoadInfo* aChildLoadInfo,
@ -583,7 +624,17 @@ ExtensionProtocolHandler::NewStream(nsIURI* aChildURI,
bool isResourceFromExtensionDir = false;
NS_TRY(extensionDir->Contains(requestedFile, &isResourceFromExtensionDir));
if (!isResourceFromExtensionDir) {
#if defined(XP_WIN)
return Err(NS_ERROR_FILE_ACCESS_DENIED);
#elif defined(MOZ_CONTENT_SANDBOX)
// On a dev build, we allow an unpacked resource that isn't
// from the extension directory as long as it is from the repo.
bool isResourceFromDevRepo = false;
MOZ_TRY(DevRepoContains(requestedFile, &isResourceFromDevRepo));
if (!isResourceFromDevRepo) {
return Err(NS_ERROR_FILE_ACCESS_DENIED);
}
#endif /* defined(XP_WIN) */
}
nsCOMPtr<nsIInputStream> inputStream;
@ -671,8 +722,18 @@ NewSimpleChannel(nsIURI* aURI,
ExtensionStreamGetter* getter) -> RequestOrReason {
MOZ_TRY(getter->GetAsync(listener, channel));
return RequestOrReason(nullptr);
});
nsresult rv;
nsCOMPtr<nsIMIMEService> mime = do_GetService("@mozilla.org/mime;1", &rv);
if (NS_SUCCEEDED(rv)) {
nsAutoCString contentType;
rv = mime->GetTypeFromURI(aURI, contentType);
if (NS_SUCCEEDED(rv)) {
Unused << channel->SetContentType(contentType);
}
}
channel.swap(*aRetVal);
}

View File

@ -148,6 +148,30 @@ private:
nsACString& aResolvedSpec,
nsIChannel** aRetVal);
#if !defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
/**
* Sets the aResult outparam to true if we are a developer build with the
* repo dir environment variable set and the requested file resides in the
* repo dir. Developer builds may load system extensions with web-accessible
* resources that are symlinks to files in the repo dir. This method is for
* checking if an unpacked resource requested by the child is from the repo.
* The requested file must be already Normalized().
*
* @param aRequestedFile the requested web-accessible resource file. Argument
* must be an nsIFile for which Normalize() has already been called.
* @param aResult outparam set to true on development builds when the
* requested file resides in the repo
*/
Result<Ok, nsresult> DevRepoContains(nsIFile* aRequestedFile, bool *aResult);
// On development builds, this points to development repo. Lazily set.
nsCOMPtr<nsIFile> mDevRepo;
// Set to true once we've already tried to load the dev repo path,
// allowing for lazy initialization of |mDevRepo|.
bool mAlreadyCheckedDevRepo;
#endif /* !defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX) */
// Used for opening JAR files off the main thread when we just need to
// obtain a file descriptor to send back to the child.
RefPtr<mozilla::LazyIdleThread> mFileOpenerThread;

View File

@ -6,11 +6,19 @@
#include "mozISandboxSettings.h"
#include "mozilla/Omnijar.h"
#include "mozilla/ModuleUtils.h"
#include "mozilla/Preferences.h"
namespace mozilla {
bool IsDevelopmentBuild()
{
nsCOMPtr<nsIFile> path = mozilla::Omnijar::GetPath(mozilla::Omnijar::GRE);
// If the path doesn't exist, we're a dev build.
return path == nullptr;
}
int GetEffectiveContentSandboxLevel() {
int level = Preferences::GetInt("security.sandbox.content.level");
// On Windows and macOS, enforce a minimum content sandbox level of 1 (except on

View File

@ -13,5 +13,11 @@ namespace mozilla {
// minimum allowed level.
int GetEffectiveContentSandboxLevel();
// Returns whether or not the currently running build is a development build -
// where development build means "the files in the .app are symlinks to the src
// directory". This check is implemented by looking for omni.ja in
// .app/Contents/Resources/.
bool IsDevelopmentBuild();
}
#endif // mozilla_SandboxPolicies_h

View File

@ -505,6 +505,7 @@ add_task(async function test_misreconciled_root() {
let engine = new BookmarksEngine(Service);
let store = engine._store;
let server = serverForFoo(engine);
await SyncTestingInfrastructure(server);
// Log real hard for this test.
store._log.trace = store._log.debug;
@ -549,6 +550,7 @@ add_task(async function test_misreconciled_root() {
do_check_eq(parentGUIDBefore, parentGUIDAfter);
do_check_eq(parentIDBefore, parentIDAfter);
await store.wipe();
await PlacesSyncUtils.bookmarks.reset();
await promiseStopServer(server);
});

View File

@ -18,39 +18,12 @@ use script_layout_interface::{PendingImage, PendingImageState};
use script_traits::PaintWorkletExecutor;
use script_traits::UntrustedNodeAddress;
use servo_url::ServoUrl;
use std::borrow::{Borrow, BorrowMut};
use std::cell::{RefCell, RefMut};
use std::collections::HashMap;
use std::hash::BuildHasherDefault;
use std::sync::{Arc, Mutex};
use std::thread;
use style::context::{SharedStyleContext, ThreadLocalStyleContext};
use style::dom::TElement;
/// TLS data scoped to the traversal.
pub struct ScopedThreadLocalLayoutContext<E: TElement> {
pub style_context: ThreadLocalStyleContext<E>,
}
impl<E: TElement> ScopedThreadLocalLayoutContext<E> {
pub fn new(context: &LayoutContext) -> Self {
ScopedThreadLocalLayoutContext {
style_context: ThreadLocalStyleContext::new(&context.style_context),
}
}
}
impl<E: TElement> Borrow<ThreadLocalStyleContext<E>> for ScopedThreadLocalLayoutContext<E> {
fn borrow(&self) -> &ThreadLocalStyleContext<E> {
&self.style_context
}
}
impl<E: TElement> BorrowMut<ThreadLocalStyleContext<E>> for ScopedThreadLocalLayoutContext<E> {
fn borrow_mut(&mut self) -> &mut ThreadLocalStyleContext<E> {
&mut self.style_context
}
}
use style::context::SharedStyleContext;
thread_local!(static FONT_CONTEXT_KEY: RefCell<Option<FontContext>> = RefCell::new(None));

View File

@ -2158,17 +2158,35 @@ impl Fragment {
let block_flow = flow.as_block();
let start_margin = block_flow.fragment.margin.block_start;
let end_margin = block_flow.fragment.margin.block_end;
if style.get_box().overflow_y == overflow_x::T::visible {
if let Some(baseline_offset) = flow.baseline_offset_of_last_line_box_in_flow() {
let ascent = baseline_offset + start_margin;
let space_below_baseline = block_flow.fragment.border_box.size.block -
baseline_offset + end_margin;
return InlineMetrics::new(ascent, space_below_baseline, baseline_offset)
}
}
let ascent = block_flow.fragment.border_box.size.block + end_margin;
let space_above_baseline = start_margin + ascent;
InlineMetrics::new(space_above_baseline, Au(0), ascent)
let border_box_block_size = block_flow.fragment.border_box.size.block;
// --------
// margin
// top -------- + +
// | |
// | |
// A ..pogo.. | + baseline_offset_of_last_line_box_in_flow()
// |
// -------- + border_box_block_size
// margin
// B --------
//
// § 10.8.1 says that the baseline (and thus ascent, which is the
// distance from the baseline to the top) should be A if it has an
// in-flow line box and if overflow: visible, and B otherwise.
let ascent =
match (flow.baseline_offset_of_last_line_box_in_flow(),
style.get_box().overflow_y) {
// Case A
(Some(baseline_offset), overflow_x::T::visible) => baseline_offset,
// Case B
_ => border_box_block_size + end_margin,
};
let space_below_baseline = border_box_block_size + end_margin - ascent;
let space_above_baseline = ascent + start_margin;
InlineMetrics::new(space_above_baseline, space_below_baseline, ascent)
}
}

View File

@ -6,7 +6,7 @@
use atomic_refcell::AtomicRefCell;
use construct::FlowConstructor;
use context::{LayoutContext, ScopedThreadLocalLayoutContext};
use context::LayoutContext;
use display_list_builder::DisplayListBuildState;
use flow::{self, PreorderFlowTraversal};
use flow::{CAN_BE_FRAGMENTED, Flow, ImmutableFlowUtils, PostorderFlowTraversal};
@ -55,10 +55,8 @@ impl<'a, E> DomTraversal<E> for RecalcStyleAndConstructFlows<'a>
E::ConcreteNode: LayoutNode,
E::FontMetricsProvider: Send,
{
type ThreadLocalContext = ScopedThreadLocalLayoutContext<E>;
fn process_preorder(&self, traversal_data: &PerLevelTraversalData,
thread_local: &mut Self::ThreadLocalContext, node: E::ConcreteNode) {
context: &mut StyleContext<E>, node: E::ConcreteNode) {
// FIXME(pcwalton): Stop allocating here. Ideally this should just be
// done by the HTML parser.
node.initialize_data();
@ -66,16 +64,12 @@ impl<'a, E> DomTraversal<E> for RecalcStyleAndConstructFlows<'a>
if !node.is_text_node() {
let el = node.as_element().unwrap();
let mut data = el.mutate_data().unwrap();
let mut context = StyleContext {
shared: &self.context.shared_context(),
thread_local: &mut thread_local.style_context,
};
recalc_style_at(self, traversal_data, &mut context, el, &mut data);
recalc_style_at(self, traversal_data, context, el, &mut data);
}
}
fn process_postorder(&self, thread_local: &mut Self::ThreadLocalContext, node: E::ConcreteNode) {
construct_flows_at(&self.context, thread_local, node);
fn process_postorder(&self, _style_context: &mut StyleContext<E>, node: E::ConcreteNode) {
construct_flows_at(&self.context, node);
}
fn text_node_needs_traversal(node: E::ConcreteNode) -> bool {
@ -100,10 +94,6 @@ impl<'a, E> DomTraversal<E> for RecalcStyleAndConstructFlows<'a>
&self.context.style_context
}
fn create_thread_local_context(&self) -> Self::ThreadLocalContext {
ScopedThreadLocalLayoutContext::new(&self.context)
}
fn is_parallel(&self) -> bool {
self.driver.is_parallel()
}
@ -118,9 +108,7 @@ pub trait PostorderNodeMutTraversal<ConcreteThreadSafeLayoutNode: ThreadSafeLayo
/// The flow construction traversal, which builds flows for styled nodes.
#[inline]
#[allow(unsafe_code)]
fn construct_flows_at<N>(context: &LayoutContext,
_thread_local: &mut ScopedThreadLocalLayoutContext<N::ConcreteElement>,
node: N)
fn construct_flows_at<N>(context: &LayoutContext, node: N)
where N: LayoutNode,
{
debug!("construct_flows_at: {:?}", node);

View File

@ -61,10 +61,13 @@ pub struct StyleSystemOptions {
pub disable_style_sharing_cache: bool,
/// Whether we should dump statistics about the style system.
pub dump_style_statistics: bool,
/// The minimum number of elements that must be traversed to trigger a dump
/// of style statistics.
pub style_statistics_threshold: usize,
}
#[cfg(feature = "gecko")]
fn get_env(name: &str) -> bool {
fn get_env_bool(name: &str) -> bool {
use std::env;
match env::var(name) {
Ok(s) => !s.is_empty(),
@ -72,6 +75,16 @@ fn get_env(name: &str) -> bool {
}
}
const DEFAULT_STATISTICS_THRESHOLD: usize = 50;
#[cfg(feature = "gecko")]
fn get_env_usize(name: &str) -> Option<usize> {
use std::env;
env::var(name).ok().map(|s| {
s.parse::<usize>().expect("Couldn't parse environmental variable as usize")
})
}
impl Default for StyleSystemOptions {
#[cfg(feature = "servo")]
fn default() -> Self {
@ -80,14 +93,17 @@ impl Default for StyleSystemOptions {
StyleSystemOptions {
disable_style_sharing_cache: opts::get().disable_share_style_cache,
dump_style_statistics: opts::get().style_sharing_stats,
style_statistics_threshold: DEFAULT_STATISTICS_THRESHOLD,
}
}
#[cfg(feature = "gecko")]
fn default() -> Self {
StyleSystemOptions {
disable_style_sharing_cache: get_env("DISABLE_STYLE_SHARING_CACHE"),
dump_style_statistics: get_env("DUMP_STYLE_STATISTICS"),
disable_style_sharing_cache: get_env_bool("DISABLE_STYLE_SHARING_CACHE"),
dump_style_statistics: get_env_bool("DUMP_STYLE_STATISTICS"),
style_statistics_threshold: get_env_usize("STYLE_STATISTICS_THRESHOLD")
.unwrap_or(DEFAULT_STATISTICS_THRESHOLD),
}
}
}
@ -615,6 +631,8 @@ pub struct TraversalStatistics {
pub traversal_time_ms: f64,
/// Whether this was a parallel traversal.
pub is_parallel: Option<bool>,
/// Whether this is a "large" traversal.
pub is_large: Option<bool>,
}
/// Implementation of Add to aggregate statistics across different threads.
@ -640,6 +658,7 @@ impl<'a> Add for &'a TraversalStatistics {
stylist_rebuilds: 0,
traversal_time_ms: 0.0,
is_parallel: None,
is_large: None,
}
}
}
@ -675,7 +694,10 @@ impl TraversalStatistics {
where E: TElement,
D: DomTraversal<E>,
{
let threshold = traversal.shared_context().options.style_statistics_threshold;
self.is_parallel = Some(traversal.is_parallel());
self.is_large = Some(self.elements_traversed as usize >= threshold);
self.traversal_time_ms = (time::precise_time_s() - start) * 1000.0;
self.selectors = traversal.shared_context().stylist.num_selectors() as u32;
self.revalidation_selectors = traversal.shared_context().stylist.num_revalidation_selectors() as u32;
@ -688,7 +710,7 @@ impl TraversalStatistics {
/// Returns whether this traversal is 'large' in order to avoid console spam
/// from lots of tiny traversals.
pub fn is_large_traversal(&self) -> bool {
self.elements_traversed >= 50
self.is_large.unwrap()
}
}

View File

@ -296,7 +296,7 @@ pub trait TElement : Eq + PartialEq + Debug + Hash + Sized + Copy + Clone +
///
/// XXXManishearth It would be better to make this a type parameter on
/// ThreadLocalStyleContext and StyleContext
type FontMetricsProvider: FontMetricsProvider;
type FontMetricsProvider: FontMetricsProvider + Send;
/// Get this element as a node.
fn as_node(&self) -> Self::ConcreteNode;

View File

@ -5,7 +5,7 @@
//! Gecko-specific bits for the styling DOM traversal.
use atomic_refcell::AtomicRefCell;
use context::{SharedStyleContext, StyleContext, ThreadLocalStyleContext};
use context::{SharedStyleContext, StyleContext};
use data::ElementData;
use dom::{NodeInfo, TNode};
use gecko::wrapper::{GeckoElement, GeckoNode};
@ -29,25 +29,19 @@ impl<'a> RecalcStyleOnly<'a> {
}
impl<'recalc, 'le> DomTraversal<GeckoElement<'le>> for RecalcStyleOnly<'recalc> {
type ThreadLocalContext = ThreadLocalStyleContext<GeckoElement<'le>>;
fn process_preorder(&self,
traversal_data: &PerLevelTraversalData,
thread_local: &mut Self::ThreadLocalContext,
context: &mut StyleContext<GeckoElement<'le>>,
node: GeckoNode<'le>)
{
if node.is_element() {
let el = node.as_element().unwrap();
let mut data = unsafe { el.ensure_data() }.borrow_mut();
let mut context = StyleContext {
shared: &self.shared,
thread_local: thread_local,
};
recalc_style_at(self, traversal_data, &mut context, el, &mut data);
recalc_style_at(self, traversal_data, context, el, &mut data);
}
}
fn process_postorder(&self, _: &mut Self::ThreadLocalContext, _: GeckoNode<'le>) {
fn process_postorder(&self, _: &mut StyleContext<GeckoElement<'le>>, _: GeckoNode<'le>) {
unreachable!();
}
@ -66,10 +60,6 @@ impl<'recalc, 'le> DomTraversal<GeckoElement<'le>> for RecalcStyleOnly<'recalc>
&self.shared
}
fn create_thread_local_context(&self) -> Self::ThreadLocalContext {
ThreadLocalStyleContext::new(&self.shared)
}
fn is_parallel(&self) -> bool {
self.driver.is_parallel()
}

View File

@ -23,7 +23,7 @@
#![deny(missing_docs)]
use arrayvec::ArrayVec;
use context::TraversalStatistics;
use context::{StyleContext, ThreadLocalStyleContext, TraversalStatistics};
use dom::{OpaqueNode, SendNode, TElement, TNode};
use rayon;
use scoped_tls::ScopedTLS;
@ -84,7 +84,7 @@ pub fn traverse_dom<E, D>(traversal: &D,
let traversal_data = PerLevelTraversalData {
current_dom_depth: depth,
};
let tls = ScopedTLS::<D::ThreadLocalContext>::new(pool);
let tls = ScopedTLS::<ThreadLocalStyleContext<E>>::new(pool);
let root = root.as_node().opaque();
pool.install(|| {
@ -124,11 +124,11 @@ pub fn traverse_dom<E, D>(traversal: &D,
#[inline(never)]
fn create_thread_local_context<'scope, E, D>(
traversal: &'scope D,
slot: &mut Option<D::ThreadLocalContext>)
slot: &mut Option<ThreadLocalStyleContext<E>>)
where E: TElement + 'scope,
D: DomTraversal<E>
{
*slot = Some(traversal.create_thread_local_context())
*slot = Some(ThreadLocalStyleContext::new(traversal.shared_context()));
}
/// A parallel top-down DOM traversal.
@ -152,7 +152,7 @@ fn top_down_dom<'a, 'scope, E, D>(nodes: &'a [SendNode<E::ConcreteNode>],
scope: &'a rayon::Scope<'scope>,
pool: &'scope rayon::ThreadPool,
traversal: &'scope D,
tls: &'scope ScopedTLS<'scope, D::ThreadLocalContext>)
tls: &'scope ScopedTLS<'scope, ThreadLocalStyleContext<E>>)
where E: TElement + 'scope,
D: DomTraversal<E>,
{
@ -167,7 +167,11 @@ fn top_down_dom<'a, 'scope, E, D>(nodes: &'a [SendNode<E::ConcreteNode>],
// Scope the borrow of the TLS so that the borrow is dropped before
// a potential recursive call when we pass TailCall.
let mut tlc = tls.ensure(
|slot: &mut Option<D::ThreadLocalContext>| create_thread_local_context(traversal, slot));
|slot: &mut Option<ThreadLocalStyleContext<E>>| create_thread_local_context(traversal, slot));
let mut context = StyleContext {
shared: traversal.shared_context(),
thread_local: &mut *tlc,
};
for n in nodes {
// If the last node we processed produced children, spawn them off
@ -199,15 +203,15 @@ fn top_down_dom<'a, 'scope, E, D>(nodes: &'a [SendNode<E::ConcreteNode>],
let node = **n;
let mut children_to_process = 0isize;
traversal.process_preorder(&traversal_data, &mut *tlc, node);
traversal.process_preorder(&traversal_data, &mut context, node);
if let Some(el) = node.as_element() {
traversal.traverse_children(&mut *tlc, el, |_tlc, kid| {
traversal.traverse_children(&mut context, el, |_context, kid| {
children_to_process += 1;
discovered_child_nodes.push(unsafe { SendNode::new(kid) })
});
}
traversal.handle_postorder_traversal(&mut *tlc, root, node,
traversal.handle_postorder_traversal(&mut context, root, node,
children_to_process);
}
}
@ -256,7 +260,7 @@ fn traverse_nodes<'a, 'scope, E, D>(nodes: &[SendNode<E::ConcreteNode>],
scope: &'a rayon::Scope<'scope>,
pool: &'scope rayon::ThreadPool,
traversal: &'scope D,
tls: &'scope ScopedTLS<'scope, D::ThreadLocalContext>)
tls: &'scope ScopedTLS<'scope, ThreadLocalStyleContext<E>>)
where E: TElement + 'scope,
D: DomTraversal<E>,
{

View File

@ -828,6 +828,10 @@ macro_rules! repeated_vec_impl {
$(impl<T: RepeatableListAnimatable> Animatable for $ty {
fn add_weighted(&self, other: &Self, self_portion: f64, other_portion: f64)
-> Result<Self, ()> {
// If the length of either list is zero, the least common multiple is undefined.
if cmp::min(self.len(), other.len()) < 1 {
return Err(());
}
use num_integer::lcm;
let len = lcm(self.len(), other.len());
self.iter().cycle().zip(other.iter().cycle()).take(len).map(|(me, you)| {
@ -842,6 +846,10 @@ macro_rules! repeated_vec_impl {
#[inline]
fn compute_squared_distance(&self, other: &Self) -> Result<f64, ()> {
// If the length of either list is zero, the least common multiple is undefined.
if cmp::min(self.len(), other.len()) < 1 {
return Err(());
}
use num_integer::lcm;
let len = lcm(self.len(), other.len());
self.iter().cycle().zip(other.iter().cycle()).take(len).map(|(me, you)| {

View File

@ -6,8 +6,8 @@
#![deny(missing_docs)]
use context::{StyleContext, ThreadLocalStyleContext};
use dom::{TElement, TNode};
use std::borrow::BorrowMut;
use std::collections::VecDeque;
use time;
use traversal::{DomTraversal, PerLevelTraversalData, PreTraverseToken};
@ -28,7 +28,12 @@ pub fn traverse_dom<E, D>(traversal: &D,
debug_assert!(token.should_traverse());
let mut discovered = VecDeque::<WorkItem<E::ConcreteNode>>::with_capacity(16);
let mut tlc = traversal.create_thread_local_context();
let mut tlc = ThreadLocalStyleContext::new(traversal.shared_context());
let mut context = StyleContext {
shared: traversal.shared_context(),
thread_local: &mut tlc,
};
let root_depth = root.depth();
if token.traverse_unstyled_children_only() {
@ -47,25 +52,24 @@ pub fn traverse_dom<E, D>(traversal: &D,
while let Some(WorkItem(node, depth)) = discovered.pop_front() {
let mut children_to_process = 0isize;
let traversal_data = PerLevelTraversalData { current_dom_depth: depth };
traversal.process_preorder(&traversal_data, &mut tlc, node);
traversal.process_preorder(&traversal_data, &mut context, node);
if let Some(el) = node.as_element() {
traversal.traverse_children(&mut tlc, el, |_tlc, kid| {
traversal.traverse_children(&mut context, el, |_context, kid| {
children_to_process += 1;
discovered.push_back(WorkItem(kid, depth + 1))
});
}
traversal.handle_postorder_traversal(&mut tlc, root.as_node().opaque(),
traversal.handle_postorder_traversal(&mut context, root.as_node().opaque(),
node, children_to_process);
}
// Dump statistics to stdout if requested.
if dump_stats {
let tlsc = tlc.borrow_mut();
tlsc.statistics.finish(traversal, start_time.unwrap());
if tlsc.statistics.is_large_traversal() {
println!("{}", tlsc.statistics);
context.thread_local.statistics.finish(traversal, start_time.unwrap());
if context.thread_local.statistics.is_large_traversal() {
println!("{}", context.thread_local.statistics);
}
}
}

View File

@ -5,7 +5,7 @@
//! Traversing the DOM tree; the bloom filter.
use atomic_refcell::AtomicRefCell;
use context::{ElementCascadeInputs, StyleContext, SharedStyleContext, ThreadLocalStyleContext};
use context::{ElementCascadeInputs, StyleContext, SharedStyleContext};
use data::{ElementData, ElementStyles};
use dom::{DirtyDescendants, NodeInfo, OpaqueNode, TElement, TNode};
use invalidation::element::restyle_hints::{RECASCADE_SELF, RECASCADE_DESCENDANTS, RestyleHint};
@ -13,7 +13,6 @@ use matching::{ChildCascadeRequirement, MatchMethods};
use sharing::{StyleSharingBehavior, StyleSharingTarget};
#[cfg(feature = "servo")] use servo_config::opts;
use smallvec::SmallVec;
use std::borrow::BorrowMut;
/// A per-traversal-level chunk of data. This is sent down by the traversal, and
/// currently only holds the dom depth for the bloom filter.
@ -138,22 +137,17 @@ fn is_servo_nonincremental_layout() -> bool {
/// A DOM Traversal trait, that is used to generically implement styling for
/// Gecko and Servo.
pub trait DomTraversal<E: TElement> : Sync {
/// The thread-local context, used to store non-thread-safe stuff that needs
/// to be used in the traversal, and of which we use one per worker, like
/// the bloom filter, for example.
type ThreadLocalContext: Send + BorrowMut<ThreadLocalStyleContext<E>>;
/// Process `node` on the way down, before its children have been processed.
fn process_preorder(&self,
data: &PerLevelTraversalData,
thread_local: &mut Self::ThreadLocalContext,
context: &mut StyleContext<E>,
node: E::ConcreteNode);
/// Process `node` on the way up, after its children have been processed.
///
/// This is only executed if `needs_postorder_traversal` returns true.
fn process_postorder(&self,
thread_local: &mut Self::ThreadLocalContext,
contect: &mut StyleContext<E>,
node: E::ConcreteNode);
/// Boolean that specifies whether a bottom up traversal should be
@ -177,7 +171,7 @@ pub trait DomTraversal<E: TElement> : Sync {
/// call durign the parallel traversal.
fn handle_postorder_traversal(
&self,
thread_local: &mut Self::ThreadLocalContext,
context: &mut StyleContext<E>,
root: OpaqueNode,
mut node: E::ConcreteNode,
children_to_process: isize
@ -190,7 +184,7 @@ pub trait DomTraversal<E: TElement> : Sync {
if children_to_process == 0 {
// We are a leaf. Walk up the chain.
loop {
self.process_postorder(thread_local, node);
self.process_postorder(context, node);
if node.opaque() == root {
break;
}
@ -404,7 +398,7 @@ pub trait DomTraversal<E: TElement> : Sync {
/// a parameter to keep the logs tidy.
fn should_traverse_children(
&self,
thread_local: &mut ThreadLocalStyleContext<E>,
context: &mut StyleContext<E>,
parent: E,
parent_data: &ElementData,
log: LogBehavior
@ -442,7 +436,7 @@ pub trait DomTraversal<E: TElement> : Sync {
// happens, we may just end up doing wasted work, since Gecko
// recursively drops Servo ElementData when the XBL insertion parent of
// an Element is changed.
if cfg!(feature = "gecko") && thread_local.is_initial_style() &&
if cfg!(feature = "gecko") && context.thread_local.is_initial_style() &&
parent_data.styles.primary().has_moz_binding() {
if log.allow() {
debug!("Parent {:?} has XBL binding, deferring traversal",
@ -458,23 +452,23 @@ pub trait DomTraversal<E: TElement> : Sync {
/// should be enqueued for processing.
fn traverse_children<F>(
&self,
thread_local: &mut Self::ThreadLocalContext,
context: &mut StyleContext<E>,
parent: E,
mut f: F
)
where
F: FnMut(&mut Self::ThreadLocalContext, E::ConcreteNode)
F: FnMut(&mut StyleContext<E>, E::ConcreteNode)
{
// Check if we're allowed to traverse past this element.
let should_traverse =
self.should_traverse_children(
thread_local.borrow_mut(),
context,
parent,
&parent.borrow_data().unwrap(),
MayLog
);
thread_local.borrow_mut().end_element(parent);
context.thread_local.end_element(parent);
if !should_traverse {
return;
}
@ -495,7 +489,7 @@ pub trait DomTraversal<E: TElement> : Sync {
}
}
}
f(thread_local, kid);
f(context, kid);
}
}
}
@ -517,9 +511,6 @@ pub trait DomTraversal<E: TElement> : Sync {
/// Return the shared style context common to all worker threads.
fn shared_context(&self) -> &SharedStyleContext;
/// Creates a thread-local context.
fn create_thread_local_context(&self) -> Self::ThreadLocalContext;
/// Whether we're performing a parallel traversal.
///
/// NB: We do this check on runtime. We could guarantee correctness in this
@ -763,7 +754,7 @@ where
// Preprocess children, propagating restyle hints and handling sibling
// relationships.
let should_traverse_children = traversal.should_traverse_children(
&mut context.thread_local,
context,
element,
&data,
DontLog

View File

@ -502,10 +502,7 @@ impl Gradient {
(&GenericGradientItem::ColorStop(ref a), &GenericGradientItem::ColorStop(ref b)) => {
match (&a.position, &b.position) {
(&Some(LengthOrPercentage::Percentage(a)), &Some(LengthOrPercentage::Percentage(b))) => {
let ordering = a.0.partial_cmp(&b.0).unwrap_or(Ordering::Equal);
if ordering != Ordering::Equal {
return ordering;
}
return a.0.partial_cmp(&b.0).unwrap_or(Ordering::Equal);
},
_ => {},
}

View File

@ -545,7 +545,7 @@ pub extern "C" fn Servo_AnimationCompose(raw_value_map: RawServoAnimationValueMa
};
if let Ok(value) = from_value.interpolate(to_value, position) {
value_map.insert(property, value);
} else if progress < 0.5 {
} else if position < 0.5 {
value_map.insert(property, from_value.clone());
} else {
value_map.insert(property, to_value.clone());

View File

@ -10,6 +10,7 @@
[TestCheckedInt]
[TestCountPopulation]
[TestCountZeroes]
[TestDefineEnum]
[TestDllInterceptor]
skip-if = os != 'win'
[TestEndian]

View File

@ -220161,7 +220161,7 @@
"testharness"
],
"web-animations/animation-model/animation-types/property-list.js": [
"9dfb34806dfd264bb1155830b0548d53fcae9007",
"31ad7b4aa12e4485f95545b087779cabb56c696c",
"support"
],
"web-animations/animation-model/animation-types/property-types.js": [

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