mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 21:31:04 +00:00
Merge mozilla-central to mozilla-inbound
This commit is contained in:
commit
3f89ce0b43
@ -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]
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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}
|
||||
|
@ -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
|
||||
|
@ -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}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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"
|
||||
|
@ -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.
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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();
|
||||
|
@ -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,
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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());
|
||||
|
@ -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.
|
||||
|
@ -113,9 +113,6 @@ FocusState::Update(uint64_t aRootLayerTreeId,
|
||||
mLastContentProcessedEvent = target.mSequenceNumber;
|
||||
return;
|
||||
}
|
||||
case FocusTarget::eSentinel: {
|
||||
MOZ_ASSERT_UNREACHABLE("Invalid FocusTargetType");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -272,9 +272,6 @@ public:
|
||||
case ScrollDirection::VERTICAL:
|
||||
EXPECT_EQ(PANNING_LOCKED_Y, mState);
|
||||
break;
|
||||
case ScrollDirection::SENTINEL:
|
||||
MOZ_ASSERT(false, "Invalid value");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<>
|
||||
|
@ -7,6 +7,7 @@
|
||||
#define ROUNDED_RECT_H
|
||||
|
||||
#include "gfxRect.h"
|
||||
#include "gfxTypes.h"
|
||||
#include "mozilla/gfx/PathHelpers.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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()) {
|
||||
|
@ -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.
|
||||
|
@ -200,7 +200,6 @@ UNIFIED_SOURCES += [
|
||||
'gfxMathTable.cpp',
|
||||
'gfxPattern.cpp',
|
||||
'gfxPlatformFontList.cpp',
|
||||
'gfxRect.cpp',
|
||||
'gfxScriptItemizer.cpp',
|
||||
'gfxSkipChars.cpp',
|
||||
'gfxSVGGlyphs.cpp',
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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"
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
10
layout/style/crashtests/1377053-1.html
Normal file
10
layout/style/crashtests/1377053-1.html
Normal file
@ -0,0 +1,10 @@
|
||||
<!doctype html>
|
||||
<style>
|
||||
div {
|
||||
animation: t 1s;
|
||||
}
|
||||
@keyframes t {
|
||||
to { stroke-dasharray: none; }
|
||||
}
|
||||
</style>
|
||||
<div></div>
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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
@ -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
146
mfbt/DefineEnum.h
Normal 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
|
@ -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',
|
||||
|
79
mfbt/tests/TestDefineEnum.cpp
Normal file
79
mfbt/tests/TestDefineEnum.cpp
Normal 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;
|
||||
}
|
@ -21,6 +21,7 @@ CppUnitTests([
|
||||
'TestCheckedInt',
|
||||
'TestCountPopulation',
|
||||
'TestCountZeroes',
|
||||
'TestDefineEnum',
|
||||
'TestDoublyLinkedList',
|
||||
'TestEndian',
|
||||
'TestEnumeratedArray',
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
});
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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>,
|
||||
{
|
||||
|
@ -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)| {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
|
@ -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());
|
||||
|
@ -10,6 +10,7 @@
|
||||
[TestCheckedInt]
|
||||
[TestCountPopulation]
|
||||
[TestCountZeroes]
|
||||
[TestDefineEnum]
|
||||
[TestDllInterceptor]
|
||||
skip-if = os != 'win'
|
||||
[TestEndian]
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user