diff options
Diffstat (limited to 'layout')
35 files changed, 589 insertions, 231 deletions
diff --git a/layout/base/nsArenaMemoryStats.h b/layout/base/nsArenaMemoryStats.h index ba09baaa4..2a872cfe8 100644 --- a/layout/base/nsArenaMemoryStats.h +++ b/layout/base/nsArenaMemoryStats.h @@ -18,7 +18,12 @@ public: Other // Everything else. }; - nsTabSizes() { mozilla::PodZero(this); } + nsTabSizes() + : mDom(0) + , mStyle(0) + , mOther(0) + { + } void add(Kind kind, size_t n) { diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index c63374541..07a5b80e7 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -7021,8 +7021,11 @@ nsCSSFrameConstructor::MaybeConstructLazily(Operation aOperation, nsIContent* aContainer, nsIContent* aChild) { + // XXXmats no lazy frames for display:contents direct descendants yet + // (Mozilla bug 979782). if (mPresShell->GetPresContext()->IsChrome() || !aContainer || - aContainer->IsInNativeAnonymousSubtree() || aContainer->IsXULElement()) { + aContainer->IsInNativeAnonymousSubtree() || aContainer->IsXULElement() || + GetDisplayContentsStyleFor(aContainer)) { return false; } @@ -7056,6 +7059,10 @@ nsCSSFrameConstructor::MaybeConstructLazily(Operation aOperation, // ignore anonymous children (eg framesets) make this complicated. So we set // these two booleans if we encounter these situations and unset them if we // hit a node with a leaf frame. + // + // Also, it's fine if one of the nodes without primary frame is a display: + // contents node except if it's the direct ancestor of the children we're + // recreating frames for. bool noPrimaryFrame = false; bool needsFrameBitSet = false; #endif @@ -7065,17 +7072,14 @@ nsCSSFrameConstructor::MaybeConstructLazily(Operation aOperation, if (content->GetPrimaryFrame() && content->GetPrimaryFrame()->IsLeaf()) { noPrimaryFrame = needsFrameBitSet = false; } - if (!noPrimaryFrame && !content->GetPrimaryFrame()) { + if (!noPrimaryFrame && !content->GetPrimaryFrame() && + !GetDisplayContentsStyleFor(content)) { noPrimaryFrame = true; } if (!needsFrameBitSet && content->HasFlag(NODE_NEEDS_FRAME)) { needsFrameBitSet = true; } #endif - // XXXmats no lazy frames for display:contents descendants yet (bug 979782). - if (GetDisplayContentsStyleFor(content)) { - return false; - } content->SetFlags(NODE_DESCENDANTS_NEED_FRAMES); content = content->GetFlattenedTreeParent(); } diff --git a/layout/base/nsCSSRendering.cpp b/layout/base/nsCSSRendering.cpp index 054632ad7..71ebfad22 100644 --- a/layout/base/nsCSSRendering.cpp +++ b/layout/base/nsCSSRendering.cpp @@ -2516,7 +2516,6 @@ nsCSSRendering::PaintGradient(nsPresContext* aPresContext, PROFILER_LABEL("nsCSSRendering", "PaintGradient", js::ProfileEntry::Category::GRAPHICS); - Telemetry::AutoTimer<Telemetry::GRADIENT_DURATION, Telemetry::Microsecond> gradientTimer; if (aDest.IsEmpty() || aFillArea.IsEmpty()) { return; } diff --git a/layout/base/nsCaret.cpp b/layout/base/nsCaret.cpp index 8ad435950..eca22f3ba 100644 --- a/layout/base/nsCaret.cpp +++ b/layout/base/nsCaret.cpp @@ -117,6 +117,12 @@ IsBidiUI() return Preferences::GetBool("bidi.browser.ui"); } +static bool +CjkThickCaret() +{ + return Preferences::GetBool("layout.cjkthickcaret"); +} + nsCaret::nsCaret() : mOverrideOffset(0) , mBlinkCount(-1) @@ -190,7 +196,7 @@ nsCaret::ComputeMetrics(nsIFrame* aFrame, int32_t aOffset, nscoord aCaretHeight) nsPresContext::CSSPixelsToAppUnits( LookAndFeel::GetInt(LookAndFeel::eIntID_CaretWidth, 1)); - if (DrawCJKCaret(aFrame, aOffset)) { + if (DrawCJKCaret(aFrame, aOffset) && CjkThickCaret()) { caretWidth += nsPresContext::CSSPixelsToAppUnits(1); } nscoord bidiIndicatorSize = nsPresContext::CSSPixelsToAppUnits(kMinBidiIndicatorPixels); diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index cb55bb2da..2bf20144a 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -7491,9 +7491,6 @@ PaintTelemetry::AutoRecordPaint::~AutoRecordPaint() double totalMs = (TimeStamp::Now() - mStart).ToMilliseconds(); - // Record the total time. - Telemetry::Accumulate(Telemetry::CONTENT_PAINT_TIME, static_cast<uint32_t>(totalMs)); - // If the total time was >= 16ms, then it's likely we missed a frame due to // painting. In this case we'll gather some detailed metrics below. if (totalMs <= 16.0) { @@ -7504,9 +7501,6 @@ PaintTelemetry::AutoRecordPaint::~AutoRecordPaint() MOZ_ASSERT(aDurationMs <= totalMs); uint32_t amount = static_cast<int32_t>((aDurationMs / totalMs) * 100.0); - - nsDependentCString key(aKey); - Telemetry::Accumulate(Telemetry::CONTENT_LARGE_PAINT_PHASE_WEIGHT, key, amount); }; double dlMs = sMetrics[Metric::DisplayList]; diff --git a/layout/base/nsDocumentViewer.cpp b/layout/base/nsDocumentViewer.cpp index 7b8734928..5478c61b0 100644 --- a/layout/base/nsDocumentViewer.cpp +++ b/layout/base/nsDocumentViewer.cpp @@ -1206,11 +1206,8 @@ nsDocumentViewer::PermitUnloadInternal(bool *aShouldPrompt, nsIDocument::PageUnloadingEventTimeStamp timestamp(mDocument); mInPermitUnload = true; - { - Telemetry::AutoTimer<Telemetry::HANDLE_BEFOREUNLOAD_MS> telemetryTimer; - EventDispatcher::DispatchDOMEvent(window, nullptr, event, mPresContext, + EventDispatcher::DispatchDOMEvent(window, nullptr, event, mPresContext, nullptr); - } mInPermitUnload = false; } @@ -1275,7 +1272,6 @@ nsDocumentViewer::PermitUnloadInternal(bool *aShouldPrompt, nsAutoSyncOperation sync(mDocument); mInPermitUnloadPrompt = true; - mozilla::Telemetry::Accumulate(mozilla::Telemetry::ONBEFOREUNLOAD_PROMPT_COUNT, 1); rv = prompt->ConfirmEx(title, message, buttonFlags, leaveLabel, stayLabel, nullptr, nullptr, &dummy, &buttonPressed); @@ -1290,15 +1286,12 @@ nsDocumentViewer::PermitUnloadInternal(bool *aShouldPrompt, // XXX: Are there other cases where prompts can abort? Is it ok to // prevent unloading the page in those cases? if (NS_FAILED(rv)) { - mozilla::Telemetry::Accumulate(mozilla::Telemetry::ONBEFOREUNLOAD_PROMPT_ACTION, 2); *aPermitUnload = false; return NS_OK; } // Button 0 == leave, button 1 == stay *aPermitUnload = (buttonPressed == 0); - mozilla::Telemetry::Accumulate(mozilla::Telemetry::ONBEFOREUNLOAD_PROMPT_ACTION, - (*aPermitUnload ? 1 : 0)); // If the user decided to go ahead, make sure not to prompt the user again // by toggling the internal prompting bool to false: if (*aPermitUnload) { @@ -1393,10 +1386,7 @@ nsDocumentViewer::PageHide(bool aIsUnload) nsIDocument::PageUnloadingEventTimeStamp timestamp(mDocument); - { - Telemetry::AutoTimer<Telemetry::HANDLE_UNLOAD_MS> telemetryTimer; - EventDispatcher::Dispatch(window, mPresContext, &event, nullptr, &status); - } + EventDispatcher::Dispatch(window, mPresContext, &event, nullptr, &status); } #ifdef MOZ_XUL diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index 062fbfe15..c1f4ad372 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -3423,7 +3423,6 @@ nsLayoutUtils::PaintFrame(nsRenderingContext* aRenderingContext, nsIFrame* aFram return NS_OK; } - TimeStamp startBuildDisplayList = TimeStamp::Now(); nsDisplayListBuilder builder(aFrame, aBuilderMode, !(aFlags & PaintFrameFlags::PAINT_HIDE_CARET)); if (aFlags & PaintFrameFlags::PAINT_IN_TRANSFORM) { @@ -3569,8 +3568,6 @@ nsLayoutUtils::PaintFrame(nsRenderingContext* aRenderingContext, nsIFrame* aFram } builder.LeavePresShell(aFrame, &list); - Telemetry::AccumulateTimeDelta(Telemetry::PAINT_BUILD_DISPLAYLIST_TIME, - startBuildDisplayList); bool profilerNeedsDisplayList = profiler_feature_active("displaylistdump"); bool consoleNeedsDisplayList = gfxUtils::DumpDisplayList() || gfxEnv::DumpPaint(); @@ -3651,8 +3648,6 @@ nsLayoutUtils::PaintFrame(nsRenderingContext* aRenderingContext, nsIFrame* aFram TimeStamp paintStart = TimeStamp::Now(); RefPtr<LayerManager> layerManager = list.PaintRoot(&builder, aRenderingContext, flags); - Telemetry::AccumulateTimeDelta(Telemetry::PAINT_RASTERIZE_TIME, - paintStart); if (gfxPrefs::GfxLoggingPaintedPixelCountEnabled()) { TimeStamp now = TimeStamp::Now(); diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index 3e5320c22..340042b46 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -1111,21 +1111,6 @@ PresShell::Destroy() LogTextPerfStats(tp, this, tp->cumulative, 0.0, eLog_totals, nullptr); } } - if (mPresContext) { - const bool mayFlushUserFontSet = false; - gfxUserFontSet* fs = mPresContext->GetUserFontSet(mayFlushUserFontSet); - if (fs) { - uint32_t fontCount; - uint64_t fontSize; - fs->GetLoadStatistics(fontCount, fontSize); - Telemetry::Accumulate(Telemetry::WEBFONT_PER_PAGE, fontCount); - Telemetry::Accumulate(Telemetry::WEBFONT_SIZE_PER_PAGE, - uint32_t(fontSize/1024)); - } else { - Telemetry::Accumulate(Telemetry::WEBFONT_PER_PAGE, 0); - Telemetry::Accumulate(Telemetry::WEBFONT_SIZE_PER_PAGE, 0); - } - } #ifdef MOZ_REFLOW_PERF DumpReflows(); @@ -2276,8 +2261,6 @@ PresShell::ScrollPage(bool aForward) nsIScrollableFrame* scrollFrame = GetFrameToScrollAsScrollable(nsIPresShell::eVertical); if (scrollFrame) { - mozilla::Telemetry::Accumulate(mozilla::Telemetry::SCROLL_INPUT_METHODS, - (uint32_t) ScrollInputMethod::MainThreadScrollPage); scrollFrame->ScrollBy(nsIntPoint(0, aForward ? 1 : -1), nsIScrollableFrame::PAGES, nsIScrollableFrame::SMOOTH, @@ -2294,9 +2277,6 @@ PresShell::ScrollLine(bool aForward) nsIScrollableFrame* scrollFrame = GetFrameToScrollAsScrollable(nsIPresShell::eVertical); if (scrollFrame) { - mozilla::Telemetry::Accumulate(mozilla::Telemetry::SCROLL_INPUT_METHODS, - (uint32_t) ScrollInputMethod::MainThreadScrollLine); - int32_t lineCount = Preferences::GetInt("toolkit.scrollbox.verticalScrollDistance", NS_DEFAULT_VERTICAL_SCROLL_DISTANCE); scrollFrame->ScrollBy(nsIntPoint(0, aForward ? lineCount : -lineCount), @@ -2315,8 +2295,6 @@ PresShell::ScrollCharacter(bool aRight) nsIScrollableFrame* scrollFrame = GetFrameToScrollAsScrollable(nsIPresShell::eHorizontal); if (scrollFrame) { - mozilla::Telemetry::Accumulate(mozilla::Telemetry::SCROLL_INPUT_METHODS, - (uint32_t) ScrollInputMethod::MainThreadScrollCharacter); int32_t h = Preferences::GetInt("toolkit.scrollbox.horizontalScrollDistance", NS_DEFAULT_HORIZONTAL_SCROLL_DISTANCE); scrollFrame->ScrollBy(nsIntPoint(aRight ? h : -h, 0), @@ -2335,8 +2313,6 @@ PresShell::CompleteScroll(bool aForward) nsIScrollableFrame* scrollFrame = GetFrameToScrollAsScrollable(nsIPresShell::eVertical); if (scrollFrame) { - mozilla::Telemetry::Accumulate(mozilla::Telemetry::SCROLL_INPUT_METHODS, - (uint32_t) ScrollInputMethod::MainThreadCompleteScroll); scrollFrame->ScrollBy(nsIntPoint(0, aForward ? 1 : -1), nsIScrollableFrame::WHOLE, nsIScrollableFrame::SMOOTH, @@ -8231,16 +8207,6 @@ PresShell::HandleEventInternal(WidgetEvent* aEvent, } } - if (Telemetry::CanRecordBase() && - !aEvent->mTimeStamp.IsNull() && - aEvent->AsInputEvent()) { - double millis = (TimeStamp::Now() - aEvent->mTimeStamp).ToMilliseconds(); - Telemetry::Accumulate(Telemetry::INPUT_EVENT_RESPONSE_MS, millis); - if (mDocument && mDocument->GetReadyStateEnum() != nsIDocument::READYSTATE_COMPLETE) { - Telemetry::Accumulate(Telemetry::LOAD_INPUT_EVENT_RESPONSE_MS, millis); - } - } - return rv; } @@ -9439,7 +9405,6 @@ PresShell::ProcessReflowCommands(bool aInterruptible) return true; } - mozilla::TimeStamp timerStart = mozilla::TimeStamp::Now(); bool interrupted = false; if (!mDirtyRoots.IsEmpty()) { @@ -9522,16 +9487,6 @@ PresShell::ProcessReflowCommands(bool aInterruptible) UnsuppressAndInvalidate(); } - if (mDocument->GetRootElement()) { - TimeDuration elapsed = TimeStamp::Now() - timerStart; - int32_t intElapsed = int32_t(elapsed.ToMilliseconds()); - - if (intElapsed > NS_LONG_REFLOW_TIME_MS) { - Telemetry::Accumulate(Telemetry::LONG_REFLOW_INTERRUPTIBLE, - aInterruptible ? 1 : 0); - } - } - return !interrupted; } diff --git a/layout/base/nsRefreshDriver.cpp b/layout/base/nsRefreshDriver.cpp index 6676bea97..b975a69dd 100644 --- a/layout/base/nsRefreshDriver.cpp +++ b/layout/base/nsRefreshDriver.cpp @@ -143,11 +143,7 @@ public: { } - virtual ~RefreshDriverTimer() - { - MOZ_ASSERT(mContentRefreshDrivers.Length() == 0, "Should have removed all content refresh drivers from here by now!"); - MOZ_ASSERT(mRootRefreshDrivers.Length() == 0, "Should have removed all root refresh drivers from here by now!"); - } + NS_INLINE_DECL_REFCOUNTING(RefreshDriverTimer) virtual void AddRefreshDriver(nsRefreshDriver* aDriver) { @@ -253,6 +249,12 @@ public: } protected: + virtual ~RefreshDriverTimer() + { + MOZ_ASSERT(mContentRefreshDrivers.Length() == 0, "Should have removed all content refresh drivers from here by now!"); + MOZ_ASSERT(mRootRefreshDrivers.Length() == 0, "Should have removed all root refresh drivers from here by now!"); + } + virtual void StartTimer() = 0; virtual void StopTimer() = 0; virtual void ScheduleNextTick(TimeStamp aNowTime) = 0; @@ -335,10 +337,11 @@ protected: nsTArray<RefPtr<nsRefreshDriver> > mRootRefreshDrivers; // useful callback for nsITimer-based derived classes, here - // bacause of c++ protected shenanigans + // because of c++ protected shenanigans static void TimerTick(nsITimer* aTimer, void* aClosure) { - RefreshDriverTimer *timer = static_cast<RefreshDriverTimer*>(aClosure); + RefPtr<RefreshDriverTimer> timer = + static_cast<RefreshDriverTimer*>(aClosure); timer->Tick(); } }; @@ -459,9 +462,7 @@ public: private: // Since VsyncObservers are refCounted, but the RefreshDriverTimer are // explicitly shutdown. We create an inner class that has the VsyncObserver - // and is shutdown when the RefreshDriverTimer is deleted. The alternative is - // to (a) make all RefreshDriverTimer RefCounted or (b) use different - // VsyncObserver types. + // and is shutdown when the RefreshDriverTimer is deleted. class RefreshDriverVsyncObserver final : public VsyncObserver { public: @@ -478,6 +479,9 @@ private: bool NotifyVsync(TimeStamp aVsyncTimestamp) override { + // IMPORTANT: All paths through this method MUST hold a strong ref on + // |this| for the duration of the TickRefreshDriver callback. + if (!NS_IsMainThread()) { MOZ_ASSERT(XRE_IsParentProcess()); // Compress vsync notifications such that only 1 may run at a time @@ -498,6 +502,7 @@ private: aVsyncTimestamp); NS_DispatchToMainThread(vsyncEvent); } else { + RefPtr<RefreshDriverVsyncObserver> kungFuDeathGrip(this); TickRefreshDriver(aVsyncTimestamp); } @@ -526,10 +531,6 @@ private: if (XRE_IsParentProcess()) { TimeDuration vsyncLatency = TimeStamp::Now() - aVsyncTimestamp; uint32_t sample = (uint32_t)vsyncLatency.ToMilliseconds(); - Telemetry::Accumulate(Telemetry::FX_REFRESH_DRIVER_CHROME_FRAME_DELAY_MS, - sample); - Telemetry::Accumulate(Telemetry::FX_REFRESH_DRIVER_SYNC_SCROLL_FRAME_DELAY_MS, - sample); RecordJank(sample); } else if (mVsyncRate != TimeDuration::Forever()) { TimeDuration contentDelay = (TimeStamp::Now() - mLastChildTick) - mVsyncRate; @@ -539,10 +540,6 @@ private: contentDelay = TimeDuration::FromMilliseconds(0); } uint32_t sample = (uint32_t)contentDelay.ToMilliseconds(); - Telemetry::Accumulate(Telemetry::FX_REFRESH_DRIVER_CONTENT_FRAME_DELAY_MS, - sample); - Telemetry::Accumulate(Telemetry::FX_REFRESH_DRIVER_SYNC_SCROLL_FRAME_DELAY_MS, - sample); RecordJank(sample); } else { // Request the vsync rate from the parent process. Might be a few vsyncs @@ -580,7 +577,9 @@ private: // the scheduled TickRefreshDriver() runs. Check mVsyncRefreshDriverTimer // before use. if (mVsyncRefreshDriverTimer) { - mVsyncRefreshDriverTimer->RunRefreshDrivers(aVsyncTimestamp); + RefPtr<VsyncRefreshDriverTimer> timer = mVsyncRefreshDriverTimer; + timer->RunRefreshDrivers(aVsyncTimestamp); + // Note: mVsyncRefreshDriverTimer might be null now. } } @@ -833,7 +832,8 @@ protected: static void TimerTickOne(nsITimer* aTimer, void* aClosure) { - InactiveRefreshDriverTimer *timer = static_cast<InactiveRefreshDriverTimer*>(aClosure); + RefPtr<InactiveRefreshDriverTimer> timer = + static_cast<InactiveRefreshDriverTimer*>(aClosure); timer->TickOne(); } @@ -885,8 +885,8 @@ NS_IMPL_ISUPPORTS(VsyncChildCreateCallback, nsIIPCBackgroundChildCreateCallback) } // namespace mozilla -static RefreshDriverTimer* sRegularRateTimer; -static InactiveRefreshDriverTimer* sThrottledRateTimer; +static StaticRefPtr<RefreshDriverTimer> sRegularRateTimer; +static StaticRefPtr<InactiveRefreshDriverTimer> sThrottledRateTimer; #ifdef XP_WIN static int32_t sHighPrecisionTimerRequests = 0; @@ -968,8 +968,6 @@ GetFirstFrameDelay(imgIRequest* req) nsRefreshDriver::Shutdown() { // clean up our timers - delete sRegularRateTimer; - delete sThrottledRateTimer; sRegularRateTimer = nullptr; sThrottledRateTimer = nullptr; @@ -2027,10 +2025,6 @@ nsRefreshDriver::Tick(int64_t aNowEpoch, TimeStamp aNowTime) notifyGC = true; } -#ifndef ANDROID /* bug 1142079 */ - mozilla::Telemetry::AccumulateTimeDelta(mozilla::Telemetry::REFRESH_DRIVER_TICK, mTickStart); -#endif - nsTObserverArray<nsAPostRefreshObserver*>::ForwardIterator iter(mPostRefreshObservers); while (iter.HasMore()) { nsAPostRefreshObserver* observer = iter.GetNext(); @@ -2237,16 +2231,15 @@ nsRefreshDriver::PVsyncActorCreated(VsyncChild* aVsyncChild) { MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(!XRE_IsParentProcess()); - auto* vsyncRefreshDriverTimer = - new VsyncRefreshDriverTimer(aVsyncChild); + RefPtr<RefreshDriverTimer> vsyncRefreshDriverTimer = + new VsyncRefreshDriverTimer(aVsyncChild); // If we are using software timer, swap current timer to // VsyncRefreshDriverTimer. if (sRegularRateTimer) { sRegularRateTimer->SwapRefreshDrivers(vsyncRefreshDriverTimer); - delete sRegularRateTimer; } - sRegularRateTimer = vsyncRefreshDriverTimer; + sRegularRateTimer = vsyncRefreshDriverTimer.forget(); } void diff --git a/layout/build/nsLayoutStatics.cpp b/layout/build/nsLayoutStatics.cpp index 0306626c4..0f4560afe 100644 --- a/layout/build/nsLayoutStatics.cpp +++ b/layout/build/nsLayoutStatics.cpp @@ -92,10 +92,6 @@ #include "nsSynthVoiceRegistry.h" #endif -#ifdef MOZ_ANDROID_OMX -#include "AndroidMediaPluginHost.h" -#endif - #include "CubebUtils.h" #include "Latency.h" #include "WebAudioUtils.h" @@ -381,11 +377,6 @@ nsLayoutStatics::Shutdown() nsAutoCopyListener::Shutdown(); FrameLayerBuilder::Shutdown(); - -#ifdef MOZ_ANDROID_OMX - AndroidMediaPluginHost::Shutdown(); -#endif - CubebUtils::ShutdownLibrary(); AsyncLatencyLogger::ShutdownLogger(); WebAudioUtils::Shutdown(); diff --git a/layout/forms/nsComboboxControlFrame.cpp b/layout/forms/nsComboboxControlFrame.cpp index f69198cc7..5a9438939 100644 --- a/layout/forms/nsComboboxControlFrame.cpp +++ b/layout/forms/nsComboboxControlFrame.cpp @@ -1040,6 +1040,9 @@ nsComboboxControlFrame::HandleRedisplayTextEvent() mRedisplayTextEvent.Forget(); ActuallyDisplayText(true); + if (!weakThis.IsAlive()) + return; + // XXXbz This should perhaps be eResize. Check. PresContext()->PresShell()->FrameNeedsReflow(mDisplayFrame, nsIPresShell::eStyleChange, diff --git a/layout/forms/nsNumberControlFrame.cpp b/layout/forms/nsNumberControlFrame.cpp index 74dec2bea..9724109cb 100644 --- a/layout/forms/nsNumberControlFrame.cpp +++ b/layout/forms/nsNumberControlFrame.cpp @@ -430,6 +430,8 @@ nsNumberControlFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements) nsContentUtils::AddScriptRunner(focusJob); } + SyncDisabledState(); + if (StyleDisplay()->mAppearance == NS_THEME_TEXTFIELD) { // The author has elected to hide the spinner by setting this // -moz-appearance. We will reframe if it changes. @@ -461,8 +463,6 @@ nsNumberControlFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements) CSSPseudoElementType::mozNumberSpinDown, spinBoxCI.mStyleContext); - SyncDisabledState(); - return rv; } diff --git a/layout/generic/nsGfxScrollFrame.cpp b/layout/generic/nsGfxScrollFrame.cpp index ccdc3a0ce..3ed3b0bb3 100644 --- a/layout/generic/nsGfxScrollFrame.cpp +++ b/layout/generic/nsGfxScrollFrame.cpp @@ -1774,6 +1774,18 @@ public: return true; } + /** + * The mCallee holds a strong ref to us since the refresh driver doesn't. + * Our dtor and mCallee's Destroy() method both call RemoveObserver() - + * whichever comes first removes us from the refresh driver. + */ + void RemoveObserver() { + if (mCallee) { + RefreshDriver(mCallee)->RemoveRefreshObserver(this, Flush_Style); + mCallee = nullptr; + } + } + private: // Private destructor, to discourage deletion outside of Release(): ~AsyncSmoothMSDScroll() { @@ -1786,17 +1798,6 @@ private: return aCallee->mOuter->PresContext()->RefreshDriver(); } - /* - * The refresh driver doesn't hold a reference to its observers, - * so releasing this object can (and is) used to remove the observer on DTOR. - * Currently, this object is released once the scrolling ends. - */ - void RemoveObserver() { - if (mCallee) { - RefreshDriver(mCallee)->RemoveRefreshObserver(this, Flush_Style); - } - } - mozilla::layers::AxisPhysicsMSDModel mXAxisModel, mYAxisModel; nsRect mRange; mozilla::TimeStamp mLastRefreshTime; @@ -1875,24 +1876,25 @@ public: ScrollFrameHelper::AsyncScrollCallback(mCallee, aTime); } -private: - ScrollFrameHelper *mCallee; - - nsRefreshDriver* RefreshDriver(ScrollFrameHelper* aCallee) { - return aCallee->mOuter->PresContext()->RefreshDriver(); - } - - /* - * The refresh driver doesn't hold a reference to its observers, - * so releasing this object can (and is) used to remove the observer on DTOR. - * Currently, this object is released once the scrolling ends. + /** + * The mCallee holds a strong ref to us since the refresh driver doesn't. + * Our dtor and mCallee's Destroy() method both call RemoveObserver() - + * whichever comes first removes us from the refresh driver. */ void RemoveObserver() { if (mCallee) { RefreshDriver(mCallee)->RemoveRefreshObserver(this, Flush_Style); APZCCallbackHelper::SuppressDisplayport(false, mCallee->mOuter->PresContext()->PresShell()); + mCallee = nullptr; } } + +private: + ScrollFrameHelper *mCallee; + + nsRefreshDriver* RefreshDriver(ScrollFrameHelper* aCallee) { + return aCallee->mOuter->PresContext()->RefreshDriver(); + } }; /* @@ -2150,8 +2152,7 @@ void ScrollFrameHelper::CompleteAsyncScroll(const nsRect &aRange, nsIAtom* aOrigin) { // Apply desired destination range since this is the last step of scrolling. - mAsyncSmoothMSDScroll = nullptr; - mAsyncScroll = nullptr; + RemoveObservers(); nsWeakFrame weakFrame(mOuter); ScrollToImpl(mDestination, aRange, aOrigin); if (!weakFrame.IsAlive()) { @@ -4586,6 +4587,20 @@ ScrollFrameHelper::Destroy() mScrollActivityTimer->Cancel(); mScrollActivityTimer = nullptr; } + RemoveObservers(); +} + +void +ScrollFrameHelper::RemoveObservers() +{ + if (mAsyncScroll) { + mAsyncScroll->RemoveObserver(); + mAsyncScroll = nullptr; + } + if (mAsyncSmoothMSDScroll) { + mAsyncSmoothMSDScroll->RemoveObserver(); + mAsyncSmoothMSDScroll = nullptr; + } } /** diff --git a/layout/generic/nsGfxScrollFrame.h b/layout/generic/nsGfxScrollFrame.h index f1ef44ae8..81bbb358f 100644 --- a/layout/generic/nsGfxScrollFrame.h +++ b/layout/generic/nsGfxScrollFrame.h @@ -638,6 +638,9 @@ protected: bool HasBgAttachmentLocal() const; uint8_t GetScrolledFrameDir() const; + // Removes any RefreshDriver observers we might have registered. + void RemoveObservers(); + static void EnsureFrameVisPrefsCached(); static bool sFrameVisPrefsCached; // The number of scrollports wide/high to expand when tracking frame visibility. diff --git a/layout/generic/nsGridContainerFrame.cpp b/layout/generic/nsGridContainerFrame.cpp index 8f117b5ab..fbd61f783 100644 --- a/layout/generic/nsGridContainerFrame.cpp +++ b/layout/generic/nsGridContainerFrame.cpp @@ -3714,8 +3714,11 @@ MeasuringReflow(nsIFrame* aChild, parent->Properties().Set( nsContainerFrame::DebugReflowingWithInfiniteISize(), true); #endif - uint32_t riFlags = ReflowInput::COMPUTE_SIZE_SHRINK_WRAP | - ReflowInput::COMPUTE_SIZE_USE_AUTO_BSIZE; + auto wm = aChild->GetWritingMode(); + uint32_t riFlags = ReflowInput::COMPUTE_SIZE_USE_AUTO_BSIZE; + if (aAvailableSize.ISize(wm) == INFINITE_ISIZE_COORD) { + riFlags |= ReflowInput::COMPUTE_SIZE_SHRINK_WRAP; + } if (aIMinSizeClamp != NS_MAXSIZE) { riFlags |= ReflowInput::I_CLAMP_MARGIN_BOX_MIN_SIZE; } @@ -3730,7 +3733,6 @@ MeasuringReflow(nsIFrame* aChild, ReflowOutput childSize(childRI); nsReflowStatus childStatus; const uint32_t flags = NS_FRAME_NO_MOVE_FRAME | NS_FRAME_NO_SIZE_VIEW; - WritingMode wm = childRI.GetWritingMode(); parent->ReflowChild(aChild, pc, childSize, childRI, wm, LogicalPoint(wm), nsSize(), flags, childStatus); parent->FinishReflowChild(aChild, pc, childSize, &childRI, wm, diff --git a/layout/generic/nsSelection.cpp b/layout/generic/nsSelection.cpp index a2227c39c..ec0fba308 100644 --- a/layout/generic/nsSelection.cpp +++ b/layout/generic/nsSelection.cpp @@ -2201,8 +2201,6 @@ nsFrameSelection::CommonPageMove(bool aForward, return; // scroll one page - mozilla::Telemetry::Accumulate(mozilla::Telemetry::SCROLL_INPUT_METHODS, - (uint32_t) ScrollInputMethod::MainThreadScrollPage); aScrollableFrame->ScrollBy(nsIntPoint(0, aForward ? 1 : -1), nsIScrollableFrame::PAGES, nsIScrollableFrame::SMOOTH); @@ -6202,11 +6200,6 @@ Selection::ScrollIntoView(SelectionRegion aRegion, flags |= nsIPresShell::SCROLL_OVERFLOW_HIDDEN; } - if (aFlags & Selection::SCROLL_FOR_CARET_MOVE) { - mozilla::Telemetry::Accumulate(mozilla::Telemetry::SCROLL_INPUT_METHODS, - (uint32_t) ScrollInputMethod::MainThreadScrollCaretIntoView); - } - presShell->ScrollFrameRectIntoView(frame, rect, aVertical, aHorizontal, flags); return NS_OK; diff --git a/layout/reftests/css-display/display-contents-dyn-insert-text-ref.html b/layout/reftests/css-display/display-contents-dyn-insert-text-ref.html new file mode 100644 index 000000000..a212e025e --- /dev/null +++ b/layout/reftests/css-display/display-contents-dyn-insert-text-ref.html @@ -0,0 +1,7 @@ +<!doctype html> +<meta charset="utf-8"> +<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io"> +<title>CSS Test reference - Bug 1338678</title> +<div style="display: contents"> + <div id="element">PASS</div> +</div> diff --git a/layout/reftests/css-display/display-contents-dyn-insert-text.html b/layout/reftests/css-display/display-contents-dyn-insert-text.html new file mode 100644 index 000000000..f3b0c0c95 --- /dev/null +++ b/layout/reftests/css-display/display-contents-dyn-insert-text.html @@ -0,0 +1,16 @@ +<!doctype html> +<meta charset="utf-8"> +<link rel="author" title="Markus Stange" href="mailto:mstange@themasta.com"> +<link rel="help" href="https://drafts.csswg.org/css-display/#box-generation"> +<title>Bug 1338678 - display:contents makes textContent disappear</title> +<div style="display: contents"> + <div id="element"></div> +</div> +<script> +window.onload = function() { + document.body.offsetTop; + var element = document.getElementById('element'); + element.textContent = "FAIL"; + element.textContent = "PASS"; +} +</script> diff --git a/layout/reftests/css-display/reftest.list b/layout/reftests/css-display/reftest.list index d310422bb..00f46a80b 100644 --- a/layout/reftests/css-display/reftest.list +++ b/layout/reftests/css-display/reftest.list @@ -24,5 +24,6 @@ skip pref(layout.css.display-contents.enabled,true) == display-contents-xbl-4.xu asserts(0-1) fuzzy-if(Android,8,3216) pref(layout.css.display-contents.enabled,true) == display-contents-fieldset.html display-contents-fieldset-ref.html # bug 1089223 asserts(1) pref(layout.css.display-contents.enabled,true) == display-contents-xbl-5.xul display-contents-xbl-3-ref.xul # bug 1089223 pref(layout.css.display-contents.enabled,true) == display-contents-list-item-child.html display-contents-list-item-child-ref.html +pref(layout.css.display-contents.enabled,true) == display-contents-dyn-insert-text.html display-contents-dyn-insert-text-ref.html pref(layout.css.display-contents.enabled,true) == display-contents-writing-mode-1.html display-contents-writing-mode-1-ref.html pref(layout.css.display-contents.enabled,true) == display-contents-writing-mode-2.html display-contents-writing-mode-2-ref.html diff --git a/layout/reftests/css-grid/bug1349571-ref.html b/layout/reftests/css-grid/bug1349571-ref.html new file mode 100644 index 000000000..42efd731a --- /dev/null +++ b/layout/reftests/css-grid/bug1349571-ref.html @@ -0,0 +1,90 @@ +<!DOCTYPE html>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html><head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8">
+ <meta charset="utf-8">
+ <title>Testcase for bug 1349571</title>
+ <style type="text/css">
+html,body {
+ color:black; background-color:white; font:16px/1 monospace; padding:0; margin:0;
+}
+
+.container {
+ display: grid;
+ grid: 250px / 500px;
+ border: 3px solid;
+ width: 500px;
+}
+
+.responsive-container {
+ background: lightgrey;
+}
+
+ </style>
+<script>try {
+(function() {
+ var target = 'blur';
+ if ( target === '' || target === '{{1}}' ) { return; }
+ var needle = 'mz_str', reText = '.?';
+ if ( needle !== '' && needle !== '{{2}}' ) {
+ reText = /^\/.+\/$/.test(needle)
+ ? needle.slice(1,-1)
+ : needle.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
+ }
+ var re = new RegExp(reText);
+ var chain = target.split('.');
+ var owner = window, prop;
+ for (;;) {
+ prop = chain.shift();
+ if ( chain.length === 0 ) { break; }
+ owner = owner[prop];
+ if ( owner instanceof Object === false ) { return; }
+ }
+ var desc = Object.getOwnPropertyDescriptor(owner, prop);
+ if ( desc && desc.get !== undefined ) { return; }
+ var magic = String.fromCharCode(Date.now() % 26 + 97) +
+ Math.floor(Math.random() * 982451653 + 982451653).toString(36);
+ var value = owner[prop];
+ var validate = function() {
+ var e = document.currentScript;
+ if ( e instanceof HTMLScriptElement && e.src === '' && re.test(e.textContent) ) {
+ throw new ReferenceError(magic);
+ }
+ };
+ Object.defineProperty(owner, prop, {
+ get: function() {
+ validate();
+ return value;
+ },
+ set: function(a) {
+ validate();
+ value = a;
+ }
+ });
+ var oe = window.onerror;
+ window.onerror = function(msg) {
+ if ( typeof msg === 'string' && msg.indexOf(magic) !== -1 ) {
+ return true;
+ }
+ if ( oe instanceof Function ) {
+ return oe.apply(this, arguments);
+ }
+ }.bind();
+})();
+} catch ( e ) { }
+(function() {
+ var c = document.currentScript, p = c && c.parentNode;
+ if ( p ) { p.removeChild(c); }
+})();</script></head>
+<body>
+
+<div class="container">
+ <div class="responsive-container"></div>
+</div>
+
+
+
+</body></html>
\ No newline at end of file diff --git a/layout/reftests/css-grid/bug1349571.html b/layout/reftests/css-grid/bug1349571.html new file mode 100644 index 000000000..f836fe36e --- /dev/null +++ b/layout/reftests/css-grid/bug1349571.html @@ -0,0 +1,94 @@ +<!DOCTYPE html>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html><head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8">
+ <meta charset="utf-8">
+ <title>Testcase for bug 1349571</title>
+ <style type="text/css">
+html,body {
+ color:black; background-color:white; font:16px/1 monospace; padding:0; margin:0;
+}
+
+.container {
+ display: grid;
+ grid-template-columns: 1fr;
+ border: 3px solid;
+ width: 500px;
+}
+
+.responsive-container {
+ padding-bottom: 50%;
+ height: 0;
+ background: lightgrey;
+}
+
+ </style>
+<script>try {
+(function() {
+ var target = 'blur';
+ if ( target === '' || target === '{{1}}' ) { return; }
+ var needle = 'mz_str', reText = '.?';
+ if ( needle !== '' && needle !== '{{2}}' ) {
+ reText = /^\/.+\/$/.test(needle)
+ ? needle.slice(1,-1)
+ : needle.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
+ }
+ var re = new RegExp(reText);
+ var chain = target.split('.');
+ var owner = window, prop;
+ for (;;) {
+ prop = chain.shift();
+ if ( chain.length === 0 ) { break; }
+ owner = owner[prop];
+ if ( owner instanceof Object === false ) { return; }
+ }
+ var desc = Object.getOwnPropertyDescriptor(owner, prop);
+ if ( desc && desc.get !== undefined ) { return; }
+ var magic = String.fromCharCode(Date.now() % 26 + 97) +
+ Math.floor(Math.random() * 982451653 + 982451653).toString(36);
+ var value = owner[prop];
+ var validate = function() {
+ var e = document.currentScript;
+ if ( e instanceof HTMLScriptElement && e.src === '' && re.test(e.textContent) ) {
+ throw new ReferenceError(magic);
+ }
+ };
+ Object.defineProperty(owner, prop, {
+ get: function() {
+ validate();
+ return value;
+ },
+ set: function(a) {
+ validate();
+ value = a;
+ }
+ });
+ var oe = window.onerror;
+ window.onerror = function(msg) {
+ if ( typeof msg === 'string' && msg.indexOf(magic) !== -1 ) {
+ return true;
+ }
+ if ( oe instanceof Function ) {
+ return oe.apply(this, arguments);
+ }
+ }.bind();
+})();
+} catch ( e ) { }
+(function() {
+ var c = document.currentScript, p = c && c.parentNode;
+ if ( p ) { p.removeChild(c); }
+})();</script></head>
+<body>
+
+<div class="container">
+ <div>
+ <div class="responsive-container"></div>
+ </div>
+</div>
+
+
+
+</body></html>
\ No newline at end of file diff --git a/layout/reftests/css-grid/bug1356820-ref.html b/layout/reftests/css-grid/bug1356820-ref.html new file mode 100644 index 000000000..b203ba203 --- /dev/null +++ b/layout/reftests/css-grid/bug1356820-ref.html @@ -0,0 +1,81 @@ +<!DOCTYPE html>
+<html><head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8"><script>try {
+(function() {
+ var target = 'blur';
+ if ( target === '' || target === '{{1}}' ) { return; }
+ var needle = 'mz_str', reText = '.?';
+ if ( needle !== '' && needle !== '{{2}}' ) {
+ reText = /^\/.+\/$/.test(needle)
+ ? needle.slice(1,-1)
+ : needle.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
+ }
+ var re = new RegExp(reText);
+ var chain = target.split('.');
+ var owner = window, prop;
+ for (;;) {
+ prop = chain.shift();
+ if ( chain.length === 0 ) { break; }
+ owner = owner[prop];
+ if ( owner instanceof Object === false ) { return; }
+ }
+ var desc = Object.getOwnPropertyDescriptor(owner, prop);
+ if ( desc && desc.get !== undefined ) { return; }
+ var magic = String.fromCharCode(Date.now() % 26 + 97) +
+ Math.floor(Math.random() * 982451653 + 982451653).toString(36);
+ var value = owner[prop];
+ var validate = function() {
+ var e = document.currentScript;
+ if ( e instanceof HTMLScriptElement && e.src === '' && re.test(e.textContent) ) {
+ throw new ReferenceError(magic);
+ }
+ };
+ Object.defineProperty(owner, prop, {
+ get: function() {
+ validate();
+ return value;
+ },
+ set: function(a) {
+ validate();
+ value = a;
+ }
+ });
+ var oe = window.onerror;
+ window.onerror = function(msg) {
+ if ( typeof msg === 'string' && msg.indexOf(magic) !== -1 ) {
+ return true;
+ }
+ if ( oe instanceof Function ) {
+ return oe.apply(this, arguments);
+ }
+ }.bind();
+})();
+} catch ( e ) { }
+(function() {
+ var c = document.currentScript, p = c && c.parentNode;
+ if ( p ) { p.removeChild(c); }
+})();</script></head><body><div style="display: grid; width: 5em;">
+ <div style="word-wrap: break-word; width: 5em; justify-self:start">
+ first item with a longlonglongword
+ </div>
+ <div>
+ second item
+ </div>
+</div>
+<div style="display: grid; width: 5em;">
+ <div style="width: 5em; justify-self:start">
+ first item with a longlonglongword
+ </div>
+ <div>
+ second item
+ </div>
+</div>
+<div style="display: grid; width: 5em;">
+ <div style="word-wrap: break-word; writing-mode:vertical-lr; justify-self:start">
+ first item with a longlonglongword
+ </div>
+ <div>
+ second item
+ </div>
+</div>
+</body></html>
\ No newline at end of file diff --git a/layout/reftests/css-grid/bug1356820.html b/layout/reftests/css-grid/bug1356820.html new file mode 100644 index 000000000..2f2f36014 --- /dev/null +++ b/layout/reftests/css-grid/bug1356820.html @@ -0,0 +1,81 @@ +<!DOCTYPE html>
+<html><head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8"><script>try {
+(function() {
+ var target = 'blur';
+ if ( target === '' || target === '{{1}}' ) { return; }
+ var needle = 'mz_str', reText = '.?';
+ if ( needle !== '' && needle !== '{{2}}' ) {
+ reText = /^\/.+\/$/.test(needle)
+ ? needle.slice(1,-1)
+ : needle.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
+ }
+ var re = new RegExp(reText);
+ var chain = target.split('.');
+ var owner = window, prop;
+ for (;;) {
+ prop = chain.shift();
+ if ( chain.length === 0 ) { break; }
+ owner = owner[prop];
+ if ( owner instanceof Object === false ) { return; }
+ }
+ var desc = Object.getOwnPropertyDescriptor(owner, prop);
+ if ( desc && desc.get !== undefined ) { return; }
+ var magic = String.fromCharCode(Date.now() % 26 + 97) +
+ Math.floor(Math.random() * 982451653 + 982451653).toString(36);
+ var value = owner[prop];
+ var validate = function() {
+ var e = document.currentScript;
+ if ( e instanceof HTMLScriptElement && e.src === '' && re.test(e.textContent) ) {
+ throw new ReferenceError(magic);
+ }
+ };
+ Object.defineProperty(owner, prop, {
+ get: function() {
+ validate();
+ return value;
+ },
+ set: function(a) {
+ validate();
+ value = a;
+ }
+ });
+ var oe = window.onerror;
+ window.onerror = function(msg) {
+ if ( typeof msg === 'string' && msg.indexOf(magic) !== -1 ) {
+ return true;
+ }
+ if ( oe instanceof Function ) {
+ return oe.apply(this, arguments);
+ }
+ }.bind();
+})();
+} catch ( e ) { }
+(function() {
+ var c = document.currentScript, p = c && c.parentNode;
+ if ( p ) { p.removeChild(c); }
+})();</script></head><body><div style="display: grid; width: 5em;">
+ <div style="word-wrap: break-word; min-width: 0;">
+ first item with a longlonglongword
+ </div>
+ <div>
+ second item
+ </div>
+</div>
+<div style="display: grid; width: 5em;">
+ <div style="min-width: 0;">
+ first item with a longlonglongword
+ </div>
+ <div>
+ second item
+ </div>
+</div>
+<div style="display: grid; width: 5em;">
+ <div style="word-wrap: break-word; min-height: 0; writing-mode:vertical-lr">
+ first item with a longlonglongword
+ </div>
+ <div>
+ second item
+ </div>
+</div>
+</body></html>
\ No newline at end of file diff --git a/layout/reftests/css-grid/reftest.list b/layout/reftests/css-grid/reftest.list index c2ee57c1a..3087ca49b 100644 --- a/layout/reftests/css-grid/reftest.list +++ b/layout/reftests/css-grid/reftest.list @@ -280,3 +280,5 @@ asserts(1-10) == grid-fragmentation-dyn4-021.html grid-fragmentation-021-ref.htm == grid-fragmentation-dyn2-031.html grid-fragmentation-031-ref.html == bug1306106.html bug1306106-ref.html == grid-percent-intrinsic-sizing-001.html grid-percent-intrinsic-sizing-001-ref.html +== bug1349571.html bug1349571-ref.html +== bug1356820.html bug1356820-ref.html diff --git a/layout/reftests/svg/reftest.list b/layout/reftests/svg/reftest.list index 520adc9e6..096628681 100644 --- a/layout/reftests/svg/reftest.list +++ b/layout/reftests/svg/reftest.list @@ -396,6 +396,7 @@ fuzzy-if(skiaContent,1,300) == tspan-xy-05.svg tspan-xy-ref.svg # bug 773482 fuzzy-if(skiaContent,1,300) == tspan-xy-06.svg tspan-xy-ref.svg # bug 773482 fuzzy-if(skiaContent,1,100) == tspan-xy-anchor-middle-01.svg tspan-xy-anchor-middle-ref.svg # bug 773482 fuzzy-if(skiaContent,1,100) == tspan-xy-anchor-end-01.svg tspan-xy-anchor-end-ref.svg # bug 773482 +== use-localRef-link.html pass.svg == userSpaceOnUse-and-pattern-01.svg userSpaceOnUse-and-pattern-01-ref.svg == viewBox-and-pattern-01.svg pass.svg == viewBox-and-pattern-02.svg pass.svg diff --git a/layout/reftests/svg/use-localRef-link.html b/layout/reftests/svg/use-localRef-link.html new file mode 100644 index 000000000..672e9ffaa --- /dev/null +++ b/layout/reftests/svg/use-localRef-link.html @@ -0,0 +1,16 @@ +<!DOCTYPE html> +<head> +<base href="/test"> +</head> +<body style="background-color: lime;"> + <svg width="100" height="100"> + <defs> + <rect id="a" x="0" y="0" width="50" height="50" fill="lime"/> + </defs> + <rect x="0" y="0" width="50" height="50" fill="red"/> + <use xlink:href="#a"/> + </svg> +</body> +</html> + + diff --git a/layout/style/FontFaceSet.cpp b/layout/style/FontFaceSet.cpp index 550a7d71a..1645adfef 100644 --- a/layout/style/FontFaceSet.cpp +++ b/layout/style/FontFaceSet.cpp @@ -1762,18 +1762,10 @@ FontFaceSet::UserFontSet::RecordFontLoadDone(uint32_t aFontSize, { mDownloadCount++; mDownloadSize += aFontSize; - Telemetry::Accumulate(Telemetry::WEBFONT_SIZE, aFontSize / 1024); if (!mFontFaceSet) { return; } - - TimeStamp navStart = mFontFaceSet->GetNavigationStartTimeStamp(); - TimeStamp zero; - if (navStart != zero) { - Telemetry::AccumulateTimeDelta(Telemetry::WEBFONT_DOWNLOAD_TIME_AFTER_START, - navStart, aDoneTime); - } } /* virtual */ nsresult diff --git a/layout/style/nsCSSParser.cpp b/layout/style/nsCSSParser.cpp index b361cf0c2..33e5fe56d 100644 --- a/layout/style/nsCSSParser.cpp +++ b/layout/style/nsCSSParser.cpp @@ -1549,6 +1549,9 @@ protected: // All data from successfully parsed properties are placed into |mData|. nsCSSExpandedDataBlock mData; + + // Value to make sure our resolved variable results stay within sane limits. + const int32_t MAX_CSS_VAR_LENGTH = 10240; public: // Used from nsCSSParser constructors and destructors @@ -2802,6 +2805,12 @@ CSSParserImpl::ResolveValueWithVariableReferencesRec( // Invalid variable with no fallback. return false; } + // Make sure we are still using sane sizes for value and + // variableValue, and abort if OOB. + if (value.Length() > MAX_CSS_VAR_LENGTH || + variableValue.Length() > MAX_CSS_VAR_LENGTH) { + return false; + } // Valid variable with no fallback. AppendTokens(value, valueFirstToken, valueLastToken, varFirstToken, varLastToken, variableValue); diff --git a/layout/style/nsFontFaceLoader.cpp b/layout/style/nsFontFaceLoader.cpp index f5a0a9f34..3082bbf87 100644 --- a/layout/style/nsFontFaceLoader.cpp +++ b/layout/style/nsFontFaceLoader.cpp @@ -205,7 +205,6 @@ nsFontFaceLoader::OnStreamComplete(nsIStreamLoader* aLoader, TimeStamp doneTime = TimeStamp::Now(); TimeDuration downloadTime = doneTime - mStartTime; uint32_t downloadTimeMS = uint32_t(downloadTime.ToMilliseconds()); - Telemetry::Accumulate(Telemetry::WEBFONT_DOWNLOAD_TIME, downloadTimeMS); if (GetFontDisplay() == NS_FONT_DISPLAY_FALLBACK) { uint32_t loadTimeout = GetFallbackDelay(); diff --git a/layout/svg/nsSVGEffects.cpp b/layout/svg/nsSVGEffects.cpp index eac094a91..e75c973c8 100644 --- a/layout/svg/nsSVGEffects.cpp +++ b/layout/svg/nsSVGEffects.cpp @@ -888,24 +888,13 @@ nsSVGEffects::InvalidateDirectRenderingObservers(nsIFrame* aFrame, uint32_t aFla } } -static already_AddRefed<nsIURI> -ResolveURLUsingLocalRef(nsIFrame* aFrame, const css::URLValueData* aURL) +already_AddRefed<nsIURI> +nsSVGEffects::GetBaseURLForLocalRef(nsIContent* content, nsIURI* aDocURI) { - MOZ_ASSERT(aFrame); - - if (!aURL) { - return nullptr; - } - - // Non-local-reference URL. - if (!aURL->IsLocalRef()) { - nsCOMPtr<nsIURI> result = aURL->GetURI(); - return result.forget(); - } + MOZ_ASSERT(content); // For a local-reference URL, resolve that fragment against the current // document that relative URLs are resolved against. - nsIContent* content = aFrame->GetContent(); nsCOMPtr<nsIURI> baseURI = content->OwnerDoc()->GetDocumentURI(); if (content->IsInAnonymousSubtree()) { @@ -933,12 +922,37 @@ ResolveURLUsingLocalRef(nsIFrame* aFrame, const css::URLValueData* aURL) } } - if (originalURI && aURL->EqualsExceptRef(originalURI)) { - baseURI = originalURI; + if (originalURI) { + bool isEqualsExceptRef = false; + aDocURI->EqualsExceptRef(originalURI, &isEqualsExceptRef); + if (isEqualsExceptRef) { + baseURI = originalURI; + } } } } + return baseURI.forget(); +} + +static already_AddRefed<nsIURI> +ResolveURLUsingLocalRef(nsIFrame* aFrame, const css::URLValueData* aURL) +{ + MOZ_ASSERT(aFrame); + + if (!aURL) { + return nullptr; + } + + // Non-local-reference URL. + if (!aURL->IsLocalRef()) { + nsCOMPtr<nsIURI> result = aURL->GetURI(); + return result.forget(); + } + + nsCOMPtr<nsIURI> baseURI = + nsSVGEffects::GetBaseURLForLocalRef(aFrame->GetContent(), aURL->GetURI()); + return aURL->ResolveLocalRef(baseURI); } diff --git a/layout/svg/nsSVGEffects.h b/layout/svg/nsSVGEffects.h index 9dd92fd31..0cf9b1500 100644 --- a/layout/svg/nsSVGEffects.h +++ b/layout/svg/nsSVGEffects.h @@ -626,11 +626,23 @@ public: static already_AddRefed<nsIURI> GetPaintURI(nsIFrame* aFrame, nsStyleSVGPaint nsStyleSVG::* aPaint); - /** + /** * A helper function to resolve SVG mask URL. */ static already_AddRefed<nsIURI> GetMaskURI(nsIFrame* aFrame, uint32_t aIndex); + + /** + * Return a baseURL for resolving a local-ref URL. + * + * @param aContent an element which uses a local-ref property. Here are some + * examples: + * <rect fill=url(#foo)> + * <circle clip-path=url(#foo)> + * <use xlink:href="#foo"> + */ + static already_AddRefed<nsIURI> + GetBaseURLForLocalRef(nsIContent* aContent, nsIURI* aDocURI); }; #endif /*NSSVGEFFECTS_H_*/ diff --git a/layout/svg/nsSVGOuterSVGFrame.cpp b/layout/svg/nsSVGOuterSVGFrame.cpp index aeadccbc5..e1b97bb40 100644 --- a/layout/svg/nsSVGOuterSVGFrame.cpp +++ b/layout/svg/nsSVGOuterSVGFrame.cpp @@ -241,8 +241,9 @@ nsSVGOuterSVGFrame::GetIntrinsicRatio() nsSVGLength2 &height = content->mLengthAttributes[SVGSVGElement::ATTR_HEIGHT]; if (!width.IsPercentage() && !height.IsPercentage()) { - nsSize ratio(NSToCoordRoundWithClamp(width.GetAnimValue(content)), - NSToCoordRoundWithClamp(height.GetAnimValue(content))); + nsSize ratio( + nsPresContext::CSSPixelsToAppUnits(width.GetAnimValue(content)), + nsPresContext::CSSPixelsToAppUnits(height.GetAnimValue(content))); if (ratio.width < 0) { ratio.width = 0; } @@ -272,8 +273,8 @@ nsSVGOuterSVGFrame::GetIntrinsicRatio() if (viewBoxHeight < 0.0f) { viewBoxHeight = 0.0f; } - return nsSize(NSToCoordRoundWithClamp(viewBoxWidth), - NSToCoordRoundWithClamp(viewBoxHeight)); + return nsSize(nsPresContext::CSSPixelsToAppUnits(viewBoxWidth), + nsPresContext::CSSPixelsToAppUnits(viewBoxHeight)); } return nsSVGDisplayContainerFrame::GetIntrinsicRatio(); diff --git a/layout/tables/nsTableFrame.cpp b/layout/tables/nsTableFrame.cpp index 5030804ed..4c11d2704 100644 --- a/layout/tables/nsTableFrame.cpp +++ b/layout/tables/nsTableFrame.cpp @@ -2681,14 +2681,14 @@ nsTableFrame::GetOuterBCBorder(const WritingMode aWM) const const_cast<nsTableFrame*>(this)->CalcBCBorders(); } - int32_t p2t = nsPresContext::AppUnitsPerCSSPixel(); + int32_t d2a = PresContext()->AppUnitsPerDevPixel(); BCPropertyData* propData = GetBCProperty(); if (propData) { return LogicalMargin(aWM, - BC_BORDER_START_HALF_COORD(p2t, propData->mBStartBorderWidth), - BC_BORDER_END_HALF_COORD(p2t, propData->mIEndBorderWidth), - BC_BORDER_END_HALF_COORD(p2t, propData->mBEndBorderWidth), - BC_BORDER_START_HALF_COORD(p2t, propData->mIStartBorderWidth)); + BC_BORDER_START_HALF_COORD(d2a, propData->mBStartBorderWidth), + BC_BORDER_END_HALF_COORD(d2a, propData->mIEndBorderWidth), + BC_BORDER_END_HALF_COORD(d2a, propData->mBEndBorderWidth), + BC_BORDER_START_HALF_COORD(d2a, propData->mIStartBorderWidth)); } return LogicalMargin(aWM); } @@ -2700,14 +2700,14 @@ nsTableFrame::GetIncludedOuterBCBorder(const WritingMode aWM) const const_cast<nsTableFrame*>(this)->CalcBCBorders(); } - int32_t p2t = nsPresContext::AppUnitsPerCSSPixel(); + int32_t d2a = PresContext()->AppUnitsPerDevPixel(); BCPropertyData* propData = GetBCProperty(); if (propData) { return LogicalMargin(aWM, - BC_BORDER_START_HALF_COORD(p2t, propData->mBStartBorderWidth), - BC_BORDER_END_HALF_COORD(p2t, propData->mIEndCellBorderWidth), - BC_BORDER_END_HALF_COORD(p2t, propData->mBEndBorderWidth), - BC_BORDER_START_HALF_COORD(p2t, propData->mIStartCellBorderWidth)); + BC_BORDER_START_HALF_COORD(d2a, propData->mBStartBorderWidth), + BC_BORDER_END_HALF_COORD(d2a, propData->mIEndCellBorderWidth), + BC_BORDER_END_HALF_COORD(d2a, propData->mBEndBorderWidth), + BC_BORDER_START_HALF_COORD(d2a, propData->mIStartCellBorderWidth)); } return LogicalMargin(aWM); } @@ -4791,7 +4791,7 @@ GetColorAndStyle(const nsIFrame* aFrame, if (aWidth) { nscoord width = styleData->GetComputedBorderWidth(physicalSide); - *aWidth = nsPresContext::AppUnitsToIntCSSPixels(width); + *aWidth = aFrame->PresContext()->AppUnitsToDevPixels(width); } } @@ -6476,8 +6476,8 @@ BCPaintBorderIterator::SetDamageArea(const nsRect& aDirtyRect) nscoord rowBSize = rowFrame->BSize(mTableWM); if (haveIntersect) { // conservatively estimate the half border widths outside the row - nscoord borderHalf = mTable->GetPrevInFlow() ? 0 : nsPresContext:: - CSSPixelsToAppUnits(rowFrame->GetBStartBCBorderWidth() + 1); + nscoord borderHalf = mTable->GetPrevInFlow() ? 0 : + mTable->PresContext()->DevPixelsToAppUnits(rowFrame->GetBStartBCBorderWidth() + 1); if (dirtyRect.BEnd(mTableWM) >= rowB - borderHalf) { nsTableRowFrame* fifRow = static_cast<nsTableRowFrame*>(rowFrame->FirstInFlow()); @@ -6487,8 +6487,8 @@ BCPaintBorderIterator::SetDamageArea(const nsRect& aDirtyRect) } else { // conservatively estimate the half border widths outside the row - nscoord borderHalf = mTable->GetNextInFlow() ? 0 : nsPresContext:: - CSSPixelsToAppUnits(rowFrame->GetBEndBCBorderWidth() + 1); + nscoord borderHalf = mTable->GetNextInFlow() ? 0 : + mTable->PresContext()->DevPixelsToAppUnits(rowFrame->GetBEndBCBorderWidth() + 1); if (rowB + rowBSize + borderHalf >= dirtyRect.BStart(mTableWM)) { mStartRg = rgFrame; mStartRow = rowFrame; @@ -6532,8 +6532,8 @@ BCPaintBorderIterator::SetDamageArea(const nsRect& aDirtyRect) nscoord colISize = colFrame->ISize(mTableWM); if (haveIntersect) { // conservatively estimate the iStart half border width outside the col - nscoord iStartBorderHalf = nsPresContext:: - CSSPixelsToAppUnits(colFrame->GetIStartBorderWidth() + 1); + nscoord iStartBorderHalf = + mTable->PresContext()->DevPixelsToAppUnits(colFrame->GetIStartBorderWidth() + 1); if (dirtyRect.IEnd(mTableWM) >= x - iStartBorderHalf) { endColIndex = colIdx; } @@ -6541,8 +6541,8 @@ BCPaintBorderIterator::SetDamageArea(const nsRect& aDirtyRect) } else { // conservatively estimate the iEnd half border width outside the col - nscoord iEndBorderHalf = nsPresContext:: - CSSPixelsToAppUnits(colFrame->GetIEndBorderWidth() + 1); + nscoord iEndBorderHalf = + mTable->PresContext()->DevPixelsToAppUnits(colFrame->GetIEndBorderWidth() + 1); if (x + colISize + iEndBorderHalf >= dirtyRect.IStart(mTableWM)) { startColIndex = endColIndex = colIdx; haveIntersect = true; @@ -6785,7 +6785,8 @@ CalcVerCornerOffset(LogicalSide aCornerOwnerSide, BCPixelSize aCornerSubWidth, BCPixelSize aHorWidth, bool aIsStartOfSeg, - bool aIsBevel) + bool aIsBevel, + nsPresContext* aPresContext) { nscoord offset = 0; // XXX These should be replaced with appropriate side-specific macros (which?) @@ -6808,7 +6809,7 @@ CalcVerCornerOffset(LogicalSide aCornerOwnerSide, offset = (aIsStartOfSeg) ? smallHalf : -largeHalf; } } - return nsPresContext::CSSPixelsToAppUnits(offset); + return aPresContext->DevPixelsToAppUnits(offset); } /** Compute the horizontal offset of a horizontal border segment @@ -6824,7 +6825,8 @@ CalcHorCornerOffset(LogicalSide aCornerOwnerSide, BCPixelSize aCornerSubWidth, BCPixelSize aVerWidth, bool aIsStartOfSeg, - bool aIsBevel) + bool aIsBevel, + nsPresContext* aPresContext) { nscoord offset = 0; // XXX These should be replaced with appropriate side-specific macros (which?) @@ -6847,7 +6849,7 @@ CalcHorCornerOffset(LogicalSide aCornerOwnerSide, offset = (aIsStartOfSeg) ? smallHalf : -largeHalf; } } - return nsPresContext::CSSPixelsToAppUnits(offset); + return aPresContext->DevPixelsToAppUnits(offset); } BCBlockDirSeg::BCBlockDirSeg() @@ -6883,10 +6885,10 @@ BCBlockDirSeg::Start(BCPaintBorderIterator& aIter, BCPixelSize maxInlineSegBSize = std::max(aIter.mPrevInlineSegBSize, aInlineSegBSize); nscoord offset = CalcVerCornerOffset(ownerSide, cornerSubWidth, maxInlineSegBSize, true, - bStartBevel); + bStartBevel, aIter.mTable->PresContext()); mBStartBevelOffset = bStartBevel ? - nsPresContext::CSSPixelsToAppUnits(maxInlineSegBSize): 0; + aIter.mTable->PresContext()->DevPixelsToAppUnits(maxInlineSegBSize): 0; // XXX this assumes that only corners where 2 segments join can be beveled mBStartBevelSide = (aInlineSegBSize > 0) ? eLogicalSideIEnd : eLogicalSideIStart; mOffsetB += offset; @@ -6944,8 +6946,8 @@ BCBlockDirSeg::GetBEndCorner(BCPaintBorderIterator& aIter, mIsBEndBevel = (mWidth > 0) ? bevel : false; mBEndInlineSegBSize = std::max(aIter.mPrevInlineSegBSize, aInlineSegBSize); mBEndOffset = CalcVerCornerOffset(ownerSide, cornerSubWidth, - mBEndInlineSegBSize, - false, mIsBEndBevel); + mBEndInlineSegBSize, false, + mIsBEndBevel, aIter.mTable->PresContext()); mLength += mBEndOffset; } @@ -7029,11 +7031,11 @@ BCBlockDirSeg::Paint(BCPaintBorderIterator& aIter, BCPixelSize smallHalf, largeHalf; DivideBCBorderSize(mWidth, smallHalf, largeHalf); LogicalRect segRect(aIter.mTableWM, - mOffsetI - nsPresContext::CSSPixelsToAppUnits(largeHalf), + mOffsetI - aIter.mTable->PresContext()->DevPixelsToAppUnits(largeHalf), mOffsetB, - nsPresContext::CSSPixelsToAppUnits(mWidth), mLength); + aIter.mTable->PresContext()->DevPixelsToAppUnits(mWidth), mLength); nscoord bEndBevelOffset = (mIsBEndBevel) ? - nsPresContext::CSSPixelsToAppUnits(mBEndInlineSegBSize) : 0; + aIter.mTable->PresContext()->DevPixelsToAppUnits(mBEndInlineSegBSize) : 0; LogicalSide bEndBevelSide = (aInlineSegBSize > 0) ? eLogicalSideIEnd : eLogicalSideIStart; @@ -7067,7 +7069,7 @@ BCBlockDirSeg::Paint(BCPaintBorderIterator& aIter, nsCSSRendering::DrawTableBorderSegment(aDrawTarget, style, color, aIter.mTableBgColor, physicalRect, appUnitsPerDevPixel, - nsPresContext::AppUnitsPerCSSPixel(), + aIter.mTable->PresContext()->AppUnitsPerDevPixel(), startBevelSide, startBevelOffset, endBevelSide, endBevelOffset); } @@ -7123,7 +7125,8 @@ BCInlineDirSeg::Start(BCPaintBorderIterator& aIter, nscoord maxBlockSegISize = std::max(aIter.mBlockDirInfo[relColIndex].mWidth, aBEndBlockSegISize); nscoord offset = CalcHorCornerOffset(cornerOwnerSide, cornerSubWidth, - maxBlockSegISize, true, iStartBevel); + maxBlockSegISize, true, iStartBevel, + aIter.mTable->PresContext()); mIStartBevelOffset = (iStartBevel && (aInlineSegBSize > 0)) ? maxBlockSegISize : 0; // XXX this assumes that only corners where 2 segments join can be beveled mIStartBevelSide = (aBEndBlockSegISize > 0) ? eLogicalSideBEnd : eLogicalSideBStart; @@ -7157,10 +7160,10 @@ BCInlineDirSeg::GetIEndCorner(BCPaintBorderIterator& aIter, nscoord verWidth = std::max(aIter.mBlockDirInfo[relColIndex].mWidth, aIStartSegISize); mEndOffset = CalcHorCornerOffset(ownerSide, cornerSubWidth, verWidth, - false, mIsIEndBevel); + false, mIsIEndBevel, aIter.mTable->PresContext()); mLength += mEndOffset; mIEndBevelOffset = (mIsIEndBevel) ? - nsPresContext::CSSPixelsToAppUnits(verWidth) : 0; + aIter.mTable->PresContext()->DevPixelsToAppUnits(verWidth) : 0; mIEndBevelSide = (aIStartSegISize > 0) ? eLogicalSideBEnd : eLogicalSideBStart; } @@ -7240,9 +7243,9 @@ BCInlineDirSeg::Paint(BCPaintBorderIterator& aIter, DrawTarget& aDrawTarget) BCPixelSize smallHalf, largeHalf; DivideBCBorderSize(mWidth, smallHalf, largeHalf); LogicalRect segRect(aIter.mTableWM, mOffsetI, - mOffsetB - nsPresContext::CSSPixelsToAppUnits(largeHalf), + mOffsetB - aIter.mTable->PresContext()->DevPixelsToAppUnits(largeHalf), mLength, - nsPresContext::CSSPixelsToAppUnits(mWidth)); + aIter.mTable->PresContext()->DevPixelsToAppUnits(mWidth)); // Convert logical to physical sides/coordinates for DrawTableBorderSegment. nsRect physicalRect = segRect.GetPhysicalRect(aIter.mTableWM, @@ -7250,7 +7253,7 @@ BCInlineDirSeg::Paint(BCPaintBorderIterator& aIter, DrawTarget& aDrawTarget) uint8_t startBevelSide = aIter.mTableWM.PhysicalSide(mIStartBevelSide); uint8_t endBevelSide = aIter.mTableWM.PhysicalSide(mIEndBevelSide); nscoord startBevelOffset = - nsPresContext::CSSPixelsToAppUnits(mIStartBevelOffset); + aIter.mTable->PresContext()->DevPixelsToAppUnits(mIStartBevelOffset); nscoord endBevelOffset = mIEndBevelOffset; // With inline-RTL directionality, the 'start' and 'end' of the inline-dir // border segment need to be swapped because DrawTableBorderSegment will @@ -7271,7 +7274,7 @@ BCInlineDirSeg::Paint(BCPaintBorderIterator& aIter, DrawTarget& aDrawTarget) nsCSSRendering::DrawTableBorderSegment(aDrawTarget, style, color, aIter.mTableBgColor, physicalRect, appUnitsPerDevPixel, - nsPresContext::AppUnitsPerCSSPixel(), + aIter.mTable->PresContext()->AppUnitsPerDevPixel(), startBevelSide, startBevelOffset, endBevelSide, endBevelOffset); } diff --git a/layout/xul/nsScrollbarButtonFrame.cpp b/layout/xul/nsScrollbarButtonFrame.cpp index 206d9717f..ff757a65f 100644 --- a/layout/xul/nsScrollbarButtonFrame.cpp +++ b/layout/xul/nsScrollbarButtonFrame.cpp @@ -171,9 +171,6 @@ nsScrollbarButtonFrame::HandleButtonPress(nsPresContext* aPresContext, return false; } - mozilla::Telemetry::Accumulate(mozilla::Telemetry::SCROLL_INPUT_METHODS, - (uint32_t) ScrollInputMethod::MainThreadScrollbarButtonClick); - if (!m) { sb->MoveToNewPosition(); if (!weakFrame.IsAlive()) { diff --git a/layout/xul/nsSliderFrame.cpp b/layout/xul/nsSliderFrame.cpp index 8e083f20c..3c1f9ef91 100644 --- a/layout/xul/nsSliderFrame.cpp +++ b/layout/xul/nsSliderFrame.cpp @@ -529,9 +529,6 @@ nsSliderFrame::HandleEvent(nsPresContext* aPresContext, return NS_OK; } - mozilla::Telemetry::Accumulate(mozilla::Telemetry::SCROLL_INPUT_METHODS, - (uint32_t) ScrollInputMethod::MainThreadScrollbarDrag); - // take our current position and subtract the start location pos -= mDragStart; bool isMouseOutsideThumb = false; @@ -598,9 +595,6 @@ nsSliderFrame::HandleEvent(nsPresContext* aPresContext, nsSize thumbSize = thumbFrame->GetSize(); nscoord thumbLength = isHorizontal ? thumbSize.width : thumbSize.height; - mozilla::Telemetry::Accumulate(mozilla::Telemetry::SCROLL_INPUT_METHODS, - (uint32_t) ScrollInputMethod::MainThreadScrollbarTrackClick); - // set it nsWeakFrame weakFrame(this); // should aMaySnap be true here? |