2016-01-11 02:28:35 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
2012-05-21 15:12:37 +04:00
|
|
|
/* 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/. */
|
2001-06-01 02:19:43 +04:00
|
|
|
|
2006-03-25 08:47:31 +03:00
|
|
|
/*
|
2018-03-22 21:20:41 +03:00
|
|
|
* structs that contain the data provided by ComputedStyle, the
|
2006-03-25 08:47:31 +03:00
|
|
|
* internal API for computed style data for an element
|
|
|
|
*/
|
|
|
|
|
2002-07-03 21:14:41 +04:00
|
|
|
#include "nsStyleStruct.h"
|
2008-07-17 10:30:25 +04:00
|
|
|
#include "nsStyleStructInlines.h"
|
2001-06-01 02:19:43 +04:00
|
|
|
#include "nsStyleConsts.h"
|
|
|
|
#include "nsString.h"
|
2004-08-01 03:15:21 +04:00
|
|
|
#include "nsPresContext.h"
|
2016-03-31 02:30:39 +03:00
|
|
|
#include "nsIAppShellService.h"
|
2009-04-02 01:59:02 +04:00
|
|
|
#include "nsIWidget.h"
|
2011-06-21 09:03:59 +04:00
|
|
|
#include "nsCRTGlue.h"
|
2009-08-21 01:52:47 +04:00
|
|
|
#include "nsCSSProps.h"
|
2016-07-29 00:51:12 +03:00
|
|
|
#include "nsDeviceContext.h"
|
|
|
|
#include "nsStyleUtil.h"
|
Bug 1552708 - Use cbindgen for URIs. r=heycam
This doesn't clean up as much as a whole, but it's a step in the right
direction. In particular, it allows us to start using simple bindings for:
* Filters
* Shapes and images, almost. Need to:
* Get rid of the complex -moz- gradient parsing (let
layout.css.simple-moz-gradient.enabled get to release).
* Counters, almost. Need to:
* Share the Attr representation with Gecko, by not using Option<>.
* Just another variant should be enough (ContentItem::{Attr,Prefixedattr},
maybe).
Which in turn allows us to remove a whole lot of bindings in followups to this.
The setup changes a bit. This also removes the double pointer I complained about
while reviewing the shared UA sheet patches. The old setup is:
```
SpecifiedUrl
* CssUrl
* Arc<CssUrlData>
* String
* UrlExtraData
* UrlValueSource
* Arc<CssUrlData>
* load id
* resolved uri
* CORS mode.
* ...
```
The new one removes the double reference to the url data via URLValue, and looks
like:
```
SpecifiedUrl
* CssUrl
* Arc<CssUrlData>
* String
* UrlExtraData
* CorsMode
* LoadData
* load id
* resolved URI
```
The LoadData is the only mutable bit that C++ can change, and is not used from
Rust. Ideally, in the future, we could just use rust-url to resolve the URL
after parsing or something, and make it all immutable. Maybe.
I've verified that this approach still works with the UA sheet patches (via the
LoadDataSource::Lazy).
The reordering of mWillChange is to avoid nsStyleDisplay from going over the
size limit. We want to split it up anyway in bug 1552587, but mBinding gains a
tag member, which means that we were having a bit of extra padding.
One thing I want to explore is to see if we can abuse rustc's non-zero
optimizations to predict the layout from C++, but that's something to explore at
some other point in time and with a lot of care and help from Michael (who sits
next to me and works on rustc ;)).
Differential Revision: https://phabricator.services.mozilla.com/D31742
2019-05-27 14:45:12 +03:00
|
|
|
#include "nsIURIMutator.h"
|
2001-06-01 02:19:43 +04:00
|
|
|
|
|
|
|
#include "nsCOMPtr.h"
|
|
|
|
|
2002-02-19 23:41:32 +03:00
|
|
|
#include "nsBidiUtils.h"
|
2011-01-13 13:40:12 +03:00
|
|
|
#include "nsLayoutUtils.h"
|
2001-06-01 02:19:43 +04:00
|
|
|
|
2004-03-09 06:57:51 +03:00
|
|
|
#include "imgIRequest.h"
|
2009-08-22 00:39:25 +04:00
|
|
|
#include "imgIContainer.h"
|
2014-06-12 05:12:00 +04:00
|
|
|
#include "CounterStyleManager.h"
|
2007-10-09 01:58:22 +04:00
|
|
|
|
2018-05-07 05:15:16 +03:00
|
|
|
#include "mozilla/dom/AnimationEffectBinding.h" // for PlaybackDirection
|
2017-03-14 16:29:55 +03:00
|
|
|
#include "mozilla/dom/DocGroup.h"
|
2016-10-13 10:04:15 +03:00
|
|
|
#include "mozilla/dom/ImageTracker.h"
|
2018-02-01 00:08:01 +03:00
|
|
|
#include "mozilla/CORSMode.h"
|
2017-08-09 04:30:25 +03:00
|
|
|
#include "mozilla/ClearOnShutdown.h"
|
2019-03-07 00:34:30 +03:00
|
|
|
#include "mozilla/PreferenceSheet.h"
|
2012-10-26 17:32:10 +04:00
|
|
|
#include "mozilla/Likely.h"
|
2013-09-07 17:01:08 +04:00
|
|
|
#include "nsIURI.h"
|
2019-01-02 16:05:23 +03:00
|
|
|
#include "mozilla/dom/Document.h"
|
2013-01-15 16:22:03 +04:00
|
|
|
#include <algorithm>
|
2017-05-02 11:20:01 +03:00
|
|
|
#include "ImageLoader.h"
|
2012-10-26 17:32:10 +04:00
|
|
|
|
2015-03-31 06:05:33 +03:00
|
|
|
using namespace mozilla;
|
2016-12-01 21:37:44 +03:00
|
|
|
using namespace mozilla::dom;
|
2015-03-31 06:05:33 +03:00
|
|
|
|
2018-11-27 22:52:13 +03:00
|
|
|
static const nscoord kMediumBorderWidth = nsPresContext::CSSPixelsToAppUnits(3);
|
|
|
|
|
2017-08-09 04:47:02 +03:00
|
|
|
// We set the size limit of style structs to 504 bytes so that when they
|
|
|
|
// are allocated by Servo side with Arc, the total size doesn't exceed
|
|
|
|
// 512 bytes, which minimizes allocator slop.
|
|
|
|
static constexpr size_t kStyleStructSizeLimit = 504;
|
2018-03-26 12:09:17 +03:00
|
|
|
#define STYLE_STRUCT(name_) \
|
2017-08-09 04:47:02 +03:00
|
|
|
static_assert(sizeof(nsStyle##name_) <= kStyleStructSizeLimit, \
|
|
|
|
"nsStyle" #name_ " became larger than the size limit");
|
|
|
|
#include "nsStyleStructList.h"
|
|
|
|
#undef STYLE_STRUCT
|
|
|
|
|
2018-11-02 21:19:06 +03:00
|
|
|
static bool DefinitelyEqualImages(const nsStyleImageRequest* aRequest1,
|
|
|
|
const nsStyleImageRequest* aRequest2) {
|
2016-11-02 11:58:31 +03:00
|
|
|
if (aRequest1 == aRequest2) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!aRequest1 || !aRequest2) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return aRequest1->DefinitelyEquals(*aRequest2);
|
|
|
|
}
|
|
|
|
|
Bug 1552708 - Use cbindgen for URIs. r=heycam
This doesn't clean up as much as a whole, but it's a step in the right
direction. In particular, it allows us to start using simple bindings for:
* Filters
* Shapes and images, almost. Need to:
* Get rid of the complex -moz- gradient parsing (let
layout.css.simple-moz-gradient.enabled get to release).
* Counters, almost. Need to:
* Share the Attr representation with Gecko, by not using Option<>.
* Just another variant should be enough (ContentItem::{Attr,Prefixedattr},
maybe).
Which in turn allows us to remove a whole lot of bindings in followups to this.
The setup changes a bit. This also removes the double pointer I complained about
while reviewing the shared UA sheet patches. The old setup is:
```
SpecifiedUrl
* CssUrl
* Arc<CssUrlData>
* String
* UrlExtraData
* UrlValueSource
* Arc<CssUrlData>
* load id
* resolved uri
* CORS mode.
* ...
```
The new one removes the double reference to the url data via URLValue, and looks
like:
```
SpecifiedUrl
* CssUrl
* Arc<CssUrlData>
* String
* UrlExtraData
* CorsMode
* LoadData
* load id
* resolved URI
```
The LoadData is the only mutable bit that C++ can change, and is not used from
Rust. Ideally, in the future, we could just use rust-url to resolve the URL
after parsing or something, and make it all immutable. Maybe.
I've verified that this approach still works with the UA sheet patches (via the
LoadDataSource::Lazy).
The reordering of mWillChange is to avoid nsStyleDisplay from going over the
size limit. We want to split it up anyway in bug 1552587, but mBinding gains a
tag member, which means that we were having a bit of extra padding.
One thing I want to explore is to see if we can abuse rustc's non-zero
optimizations to predict the layout from C++, but that's something to explore at
some other point in time and with a lot of care and help from Michael (who sits
next to me and works on rustc ;)).
Differential Revision: https://phabricator.services.mozilla.com/D31742
2019-05-27 14:45:12 +03:00
|
|
|
bool StyleCssUrlData::operator==(const StyleCssUrlData& aOther) const {
|
|
|
|
// This very intentionally avoids comparing LoadData and such.
|
|
|
|
const auto& extra = extra_data.get();
|
|
|
|
const auto& otherExtra = aOther.extra_data.get();
|
|
|
|
if (extra.BaseURI() != otherExtra.BaseURI() ||
|
|
|
|
extra.Principal() != otherExtra.Principal() ||
|
|
|
|
cors_mode != aOther.cors_mode) {
|
|
|
|
// NOTE(emilio): This does pointer comparison, but it's what URLValue used
|
|
|
|
// to do. That's ok though since this is only used for style struct diffing.
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return serialization == aOther.serialization;
|
|
|
|
}
|
|
|
|
|
|
|
|
StyleLoadData::~StyleLoadData() {
|
|
|
|
if (load_id != 0) {
|
|
|
|
css::ImageLoader::DeregisterCSSImageFromAllLoaders(*this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
already_AddRefed<nsIURI> StyleComputedUrl::ResolveLocalRef(nsIURI* aURI) const {
|
|
|
|
nsCOMPtr<nsIURI> result = GetURI();
|
|
|
|
if (result && IsLocalRef()) {
|
|
|
|
nsCString ref;
|
|
|
|
result->GetRef(ref);
|
|
|
|
|
|
|
|
nsresult rv = NS_MutateURI(aURI).SetRef(ref).Finalize(result);
|
|
|
|
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
// If setting the ref failed, just return the original URI.
|
|
|
|
result = aURI;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result.forget();
|
|
|
|
}
|
|
|
|
|
|
|
|
already_AddRefed<nsIURI> StyleComputedUrl::ResolveLocalRef(
|
|
|
|
const nsIContent* aContent) const {
|
|
|
|
nsCOMPtr<nsIURI> url = aContent->GetBaseURI();
|
|
|
|
return ResolveLocalRef(url);
|
|
|
|
}
|
|
|
|
|
|
|
|
imgRequestProxy* StyleComputedUrl::LoadImage(Document& aDocument) {
|
|
|
|
MOZ_DIAGNOSTIC_ASSERT(NS_IsMainThread());
|
|
|
|
|
|
|
|
static uint64_t sNextLoadID = 1;
|
|
|
|
|
|
|
|
StyleLoadData& data = LoadData();
|
|
|
|
if (data.load_id == 0) {
|
|
|
|
data.load_id = sNextLoadID++;
|
|
|
|
}
|
|
|
|
|
|
|
|
// NB: If aDocument is not the original document, we may not be able to load
|
|
|
|
// images from aDocument. Instead we do the image load from the original doc
|
|
|
|
// and clone it to aDocument.
|
|
|
|
Document* loadingDoc = aDocument.GetOriginalDocument();
|
|
|
|
if (!loadingDoc) {
|
|
|
|
loadingDoc = &aDocument;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Kick off the load in the loading document.
|
|
|
|
css::ImageLoader::LoadImage(*this, *loadingDoc);
|
|
|
|
|
|
|
|
// Register the image in the document that's using it.
|
|
|
|
return aDocument.StyleImageLoader()->RegisterCSSImage(data);
|
|
|
|
}
|
|
|
|
|
2001-06-01 02:19:43 +04:00
|
|
|
// --------------------
|
|
|
|
// nsStyleFont
|
|
|
|
//
|
|
|
|
nsStyleFont::nsStyleFont(const nsStyleFont& aSrc)
|
2008-01-09 12:38:28 +03:00
|
|
|
: mFont(aSrc.mFont),
|
|
|
|
mSize(aSrc.mSize),
|
2017-09-12 23:53:39 +03:00
|
|
|
mFontSizeFactor(aSrc.mFontSizeFactor),
|
|
|
|
mFontSizeOffset(aSrc.mFontSizeOffset),
|
|
|
|
mFontSizeKeyword(aSrc.mFontSizeKeyword),
|
2008-10-10 18:56:18 +04:00
|
|
|
mGenericID(aSrc.mGenericID),
|
2008-01-09 12:38:28 +03:00
|
|
|
mScriptLevel(aSrc.mScriptLevel),
|
2013-12-02 20:49:00 +04:00
|
|
|
mMathVariant(aSrc.mMathVariant),
|
2014-01-14 18:39:50 +04:00
|
|
|
mMathDisplay(aSrc.mMathDisplay),
|
2015-10-08 02:19:29 +03:00
|
|
|
mMinFontSizeRatio(aSrc.mMinFontSizeRatio),
|
2012-08-21 06:23:32 +04:00
|
|
|
mExplicitLanguage(aSrc.mExplicitLanguage),
|
2013-06-29 07:28:50 +04:00
|
|
|
mAllowZoom(aSrc.mAllowZoom),
|
2008-01-09 12:38:28 +03:00
|
|
|
mScriptUnconstrainedSize(aSrc.mScriptUnconstrainedSize),
|
|
|
|
mScriptMinSize(aSrc.mScriptMinSize),
|
2008-02-19 10:36:50 +03:00
|
|
|
mScriptSizeMultiplier(aSrc.mScriptSizeMultiplier),
|
2012-01-24 17:09:55 +04:00
|
|
|
mLanguage(aSrc.mLanguage) {
|
2009-08-07 18:38:44 +04:00
|
|
|
MOZ_COUNT_CTOR(nsStyleFont);
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
|
|
|
|
2019-01-18 20:32:22 +03:00
|
|
|
nsStyleFont::nsStyleFont(const Document& aDocument)
|
|
|
|
: mFont(*aDocument.GetFontPrefsForLang(nullptr)->GetDefaultFont(
|
2019-04-02 00:47:59 +03:00
|
|
|
StyleGenericFontFamily::None)),
|
2019-01-18 20:32:22 +03:00
|
|
|
mSize(ZoomText(aDocument, mFont.size)),
|
2018-09-11 17:44:38 +03:00
|
|
|
mFontSizeFactor(1.0),
|
|
|
|
mFontSizeOffset(0),
|
|
|
|
mFontSizeKeyword(NS_STYLE_FONT_SIZE_MEDIUM),
|
2019-04-02 00:47:59 +03:00
|
|
|
mGenericID(StyleGenericFontFamily::None),
|
2018-09-11 17:44:38 +03:00
|
|
|
mScriptLevel(0),
|
|
|
|
mMathVariant(NS_MATHML_MATHVARIANT_NONE),
|
|
|
|
mMathDisplay(NS_MATHML_DISPLAYSTYLE_INLINE),
|
2018-12-05 21:44:05 +03:00
|
|
|
mMinFontSizeRatio(100), // 100%
|
2018-09-11 17:44:38 +03:00
|
|
|
mExplicitLanguage(false),
|
|
|
|
mAllowZoom(true),
|
|
|
|
mScriptUnconstrainedSize(mSize),
|
|
|
|
mScriptMinSize(nsPresContext::CSSTwipsToAppUnits(
|
|
|
|
NS_POINTS_TO_TWIPS(NS_MATHML_DEFAULT_SCRIPT_MIN_SIZE_PT))),
|
|
|
|
mScriptSizeMultiplier(NS_MATHML_DEFAULT_SCRIPT_SIZE_MULTIPLIER),
|
2019-01-18 20:32:22 +03:00
|
|
|
mLanguage(aDocument.GetLanguageForStyle()) {
|
2018-09-11 17:44:38 +03:00
|
|
|
MOZ_COUNT_CTOR(nsStyleFont);
|
2017-08-23 13:14:03 +03:00
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
2019-01-22 17:52:41 +03:00
|
|
|
mFont.size = mSize;
|
2019-01-18 20:32:22 +03:00
|
|
|
if (!nsContentUtils::IsChromeDoc(&aDocument)) {
|
2019-01-22 17:52:41 +03:00
|
|
|
nscoord minimumFontSize =
|
2019-01-18 20:32:22 +03:00
|
|
|
aDocument.GetFontPrefsForLang(mLanguage)->mMinimumFontSize;
|
2017-08-23 13:14:03 +03:00
|
|
|
mFont.size = std::max(mSize, minimumFontSize);
|
|
|
|
}
|
2003-03-13 18:29:36 +03:00
|
|
|
}
|
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
nsChangeHint nsStyleFont::CalcDifference(const nsStyleFont& aNewData) const {
|
|
|
|
MOZ_ASSERT(mAllowZoom == aNewData.mAllowZoom,
|
2013-06-29 07:28:50 +04:00
|
|
|
"expected mAllowZoom to be the same on both nsStyleFonts");
|
2016-06-21 04:47:54 +03:00
|
|
|
if (mSize != aNewData.mSize || mLanguage != aNewData.mLanguage ||
|
|
|
|
mExplicitLanguage != aNewData.mExplicitLanguage ||
|
|
|
|
mMathVariant != aNewData.mMathVariant ||
|
|
|
|
mMathDisplay != aNewData.mMathDisplay ||
|
|
|
|
mMinFontSizeRatio != aNewData.mMinFontSizeRatio) {
|
2012-01-24 17:09:55 +04:00
|
|
|
return NS_STYLE_HINT_REFLOW;
|
2001-09-27 22:33:58 +04:00
|
|
|
}
|
2014-09-05 07:48:43 +04:00
|
|
|
|
2017-11-08 07:01:29 +03:00
|
|
|
switch (mFont.CalcDifference(aNewData.mFont)) {
|
|
|
|
case nsFont::MaxDifference::eLayoutAffecting:
|
|
|
|
return NS_STYLE_HINT_REFLOW;
|
|
|
|
|
|
|
|
case nsFont::MaxDifference::eVisual:
|
|
|
|
return NS_STYLE_HINT_VISUAL;
|
|
|
|
|
|
|
|
case nsFont::MaxDifference::eNone:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2014-09-05 07:48:43 +04:00
|
|
|
// XXX Should any of these cause a non-nsChangeHint_NeutralChange change?
|
2016-06-21 04:47:54 +03:00
|
|
|
if (mGenericID != aNewData.mGenericID ||
|
|
|
|
mScriptLevel != aNewData.mScriptLevel ||
|
|
|
|
mScriptUnconstrainedSize != aNewData.mScriptUnconstrainedSize ||
|
|
|
|
mScriptMinSize != aNewData.mScriptMinSize ||
|
|
|
|
mScriptSizeMultiplier != aNewData.mScriptSizeMultiplier) {
|
2014-09-05 07:48:43 +04:00
|
|
|
return nsChangeHint_NeutralChange;
|
|
|
|
}
|
|
|
|
|
2016-07-17 17:20:21 +03:00
|
|
|
return nsChangeHint(0);
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
|
|
|
|
2019-01-18 20:32:22 +03:00
|
|
|
nscoord nsStyleFont::ZoomText(const Document& aDocument, nscoord aSize) {
|
|
|
|
float textZoom = 1.0;
|
|
|
|
if (auto* pc = aDocument.GetPresContext()) {
|
|
|
|
textZoom = pc->EffectiveTextZoom();
|
|
|
|
}
|
2015-11-16 19:32:39 +03:00
|
|
|
// aSize can be negative (e.g.: calc(-1px)) so we can't assert that here.
|
|
|
|
// The caller is expected deal with that.
|
2019-01-18 20:32:22 +03:00
|
|
|
return NSToCoordTruncClamped(float(aSize) * textZoom);
|
2003-03-13 18:29:36 +03:00
|
|
|
}
|
|
|
|
|
2019-01-26 13:00:44 +03:00
|
|
|
template <typename T>
|
|
|
|
static StyleRect<T> StyleRectWithAllSides(const T& aSide) {
|
|
|
|
return {aSide, aSide, aSide, aSide};
|
|
|
|
}
|
|
|
|
|
|
|
|
nsStyleMargin::nsStyleMargin(const Document& aDocument)
|
|
|
|
: mMargin(StyleRectWithAllSides(
|
2019-02-18 05:25:54 +03:00
|
|
|
LengthPercentageOrAuto::LengthPercentage(LengthPercentage::Zero()))),
|
|
|
|
mScrollMargin(StyleRectWithAllSides(StyleLength{0.})) {
|
2009-08-07 18:38:44 +04:00
|
|
|
MOZ_COUNT_CTOR(nsStyleMargin);
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
|
|
|
|
2014-07-16 09:27:12 +04:00
|
|
|
nsStyleMargin::nsStyleMargin(const nsStyleMargin& aSrc)
|
2019-02-18 05:25:54 +03:00
|
|
|
: mMargin(aSrc.mMargin), mScrollMargin(aSrc.mScrollMargin) {
|
2009-08-07 18:38:44 +04:00
|
|
|
MOZ_COUNT_CTOR(nsStyleMargin);
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
nsChangeHint nsStyleMargin::CalcDifference(
|
|
|
|
const nsStyleMargin& aNewData) const {
|
2019-04-11 09:21:36 +03:00
|
|
|
if (mMargin == aNewData.mMargin && mScrollMargin == aNewData.mScrollMargin) {
|
2016-07-17 17:20:21 +03:00
|
|
|
return nsChangeHint(0);
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
2019-04-11 09:21:36 +03:00
|
|
|
|
|
|
|
nsChangeHint hint = nsChangeHint(0);
|
|
|
|
|
|
|
|
if (mMargin != aNewData.mMargin) {
|
|
|
|
// Margin differences can't affect descendant intrinsic sizes and
|
|
|
|
// don't need to force children to reflow.
|
|
|
|
hint |= nsChangeHint_NeedReflow | nsChangeHint_ReflowChangesSizeOrPosition |
|
|
|
|
nsChangeHint_ClearAncestorIntrinsics;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mScrollMargin != aNewData.mScrollMargin) {
|
|
|
|
// FIXME: Bug 1530253 Support re-snapping when scroll-margin changes.
|
|
|
|
hint |= nsChangeHint_NeutralChange;
|
|
|
|
}
|
|
|
|
|
|
|
|
return hint;
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
|
|
|
|
2019-01-26 13:00:44 +03:00
|
|
|
nsStylePadding::nsStylePadding(const Document& aDocument)
|
2019-02-18 05:46:09 +03:00
|
|
|
: mPadding(StyleRectWithAllSides(LengthPercentage::Zero())),
|
|
|
|
mScrollPadding(StyleRectWithAllSides(LengthPercentageOrAuto::Auto())) {
|
2009-08-07 18:38:44 +04:00
|
|
|
MOZ_COUNT_CTOR(nsStylePadding);
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
|
|
|
|
2014-07-16 09:27:12 +04:00
|
|
|
nsStylePadding::nsStylePadding(const nsStylePadding& aSrc)
|
2019-02-18 05:46:09 +03:00
|
|
|
: mPadding(aSrc.mPadding), mScrollPadding(aSrc.mScrollPadding) {
|
2009-08-07 18:38:44 +04:00
|
|
|
MOZ_COUNT_CTOR(nsStylePadding);
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
nsChangeHint nsStylePadding::CalcDifference(
|
|
|
|
const nsStylePadding& aNewData) const {
|
2019-04-11 09:21:48 +03:00
|
|
|
if (mPadding == aNewData.mPadding &&
|
|
|
|
mScrollPadding == aNewData.mScrollPadding) {
|
2016-07-17 17:20:21 +03:00
|
|
|
return nsChangeHint(0);
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
2019-04-11 09:21:48 +03:00
|
|
|
|
|
|
|
nsChangeHint hint = nsChangeHint(0);
|
|
|
|
|
|
|
|
if (mPadding != aNewData.mPadding) {
|
|
|
|
// Padding differences can't affect descendant intrinsic sizes, but do need
|
|
|
|
// to force children to reflow so that we can reposition them, since their
|
|
|
|
// offsets are from our frame bounds but our content rect's position within
|
|
|
|
// those bounds is moving.
|
|
|
|
// FIXME: It would be good to return a weaker hint here that doesn't
|
|
|
|
// force reflow of all descendants, but the hint would need to force
|
|
|
|
// reflow of the frame's children (see how
|
|
|
|
// ReflowInput::InitResizeFlags initializes the inline-resize flag).
|
|
|
|
hint |= NS_STYLE_HINT_REFLOW & ~nsChangeHint_ClearDescendantIntrinsics;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mScrollPadding != aNewData.mScrollPadding) {
|
|
|
|
// FIXME: Bug 1530253 Support re-snapping when scroll-padding changes.
|
|
|
|
hint |= nsChangeHint_NeutralChange;
|
|
|
|
}
|
|
|
|
|
|
|
|
return hint;
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
|
|
|
|
2019-01-18 20:32:22 +03:00
|
|
|
static nscoord TwipsPerPixel(const Document& aDocument) {
|
|
|
|
auto* pc = aDocument.GetPresContext();
|
|
|
|
return pc ? pc->AppUnitsPerDevPixel() : mozilla::AppUnitsPerCSSPixel();
|
|
|
|
}
|
|
|
|
|
2019-02-24 21:47:53 +03:00
|
|
|
static inline BorderRadius ZeroBorderRadius() {
|
|
|
|
auto zero = LengthPercentage::Zero();
|
|
|
|
return {{{zero, zero}}, {{zero, zero}}, {{zero, zero}}, {{zero, zero}}};
|
|
|
|
}
|
|
|
|
|
2019-01-18 20:32:22 +03:00
|
|
|
nsStyleBorder::nsStyleBorder(const Document& aDocument)
|
2019-02-24 21:47:53 +03:00
|
|
|
: mBorderRadius(ZeroBorderRadius()),
|
2019-05-22 00:07:55 +03:00
|
|
|
mBorderImageWidth(
|
|
|
|
StyleRectWithAllSides(StyleBorderImageSideWidth::Number(1.))),
|
2019-02-24 21:47:53 +03:00
|
|
|
mBorderImageOutset(
|
2019-02-14 21:03:04 +03:00
|
|
|
StyleRectWithAllSides(StyleNonNegativeLengthOrNumber::Number(0.))),
|
|
|
|
mBorderImageSlice(
|
|
|
|
{StyleRectWithAllSides(StyleNumberOrPercentage::Percentage({1.})),
|
|
|
|
false}),
|
2017-12-21 08:16:40 +03:00
|
|
|
mBorderImageRepeatH(StyleBorderImageRepeat::Stretch),
|
|
|
|
mBorderImageRepeatV(StyleBorderImageRepeat::Stretch),
|
2016-07-25 09:26:05 +03:00
|
|
|
mFloatEdge(StyleFloatEdge::ContentBox),
|
2016-08-26 10:14:32 +03:00
|
|
|
mBoxDecorationBreak(StyleBoxDecorationBreak::Slice),
|
2019-04-04 14:35:33 +03:00
|
|
|
mBorderTopColor(StyleColor::CurrentColor()),
|
|
|
|
mBorderRightColor(StyleColor::CurrentColor()),
|
|
|
|
mBorderBottomColor(StyleColor::CurrentColor()),
|
|
|
|
mBorderLeftColor(StyleColor::CurrentColor()),
|
2019-01-18 20:32:22 +03:00
|
|
|
mComputedBorder(0, 0, 0, 0),
|
|
|
|
mTwipsPerPixel(TwipsPerPixel(aDocument)) {
|
2009-08-07 18:38:44 +04:00
|
|
|
MOZ_COUNT_CTOR(nsStyleBorder);
|
2011-12-23 03:34:45 +04:00
|
|
|
|
2018-11-27 22:52:13 +03:00
|
|
|
nscoord medium = kMediumBorderWidth;
|
2005-04-29 19:44:38 +04:00
|
|
|
NS_FOR_CSS_SIDES(side) {
|
2011-04-19 07:07:22 +04:00
|
|
|
mBorder.Side(side) = medium;
|
2018-11-07 22:56:17 +03:00
|
|
|
mBorderStyle[side] = StyleBorderStyle::None;
|
2008-10-01 09:50:52 +04:00
|
|
|
}
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
nsStyleBorder::nsStyleBorder(const nsStyleBorder& aSrc)
|
2017-09-18 06:38:39 +03:00
|
|
|
: mBorderRadius(aSrc.mBorderRadius),
|
2016-06-03 18:56:54 +03:00
|
|
|
mBorderImageSource(aSrc.mBorderImageSource),
|
|
|
|
mBorderImageWidth(aSrc.mBorderImageWidth),
|
|
|
|
mBorderImageOutset(aSrc.mBorderImageOutset),
|
2019-02-14 21:03:04 +03:00
|
|
|
mBorderImageSlice(aSrc.mBorderImageSlice),
|
2016-06-03 18:56:54 +03:00
|
|
|
mBorderImageRepeatH(aSrc.mBorderImageRepeatH),
|
|
|
|
mBorderImageRepeatV(aSrc.mBorderImageRepeatV),
|
|
|
|
mFloatEdge(aSrc.mFloatEdge),
|
|
|
|
mBoxDecorationBreak(aSrc.mBoxDecorationBreak),
|
2018-06-05 04:24:12 +03:00
|
|
|
mBorderTopColor(aSrc.mBorderTopColor),
|
|
|
|
mBorderRightColor(aSrc.mBorderRightColor),
|
|
|
|
mBorderBottomColor(aSrc.mBorderBottomColor),
|
|
|
|
mBorderLeftColor(aSrc.mBorderLeftColor),
|
2016-06-03 18:56:54 +03:00
|
|
|
mComputedBorder(aSrc.mComputedBorder),
|
|
|
|
mBorder(aSrc.mBorder),
|
|
|
|
mTwipsPerPixel(aSrc.mTwipsPerPixel) {
|
2009-08-07 18:38:44 +04:00
|
|
|
MOZ_COUNT_CTOR(nsStyleBorder);
|
2008-07-08 04:56:52 +04:00
|
|
|
NS_FOR_CSS_SIDES(side) { mBorderStyle[side] = aSrc.mBorderStyle[side]; }
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
|
|
|
|
2008-07-17 10:30:25 +04:00
|
|
|
nsStyleBorder::~nsStyleBorder() { MOZ_COUNT_DTOR(nsStyleBorder); }
|
|
|
|
|
2019-02-04 19:03:25 +03:00
|
|
|
void nsStyleBorder::TriggerImageLoads(Document& aDocument,
|
|
|
|
const nsStyleBorder* aOldStyle) {
|
2016-11-02 11:58:32 +03:00
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
|
2018-02-22 21:44:44 +03:00
|
|
|
mBorderImageSource.ResolveImage(
|
2019-02-02 21:42:25 +03:00
|
|
|
aDocument, aOldStyle ? &aOldStyle->mBorderImageSource : nullptr);
|
2016-11-02 11:58:32 +03:00
|
|
|
}
|
|
|
|
|
2011-12-23 03:34:45 +04:00
|
|
|
nsMargin nsStyleBorder::GetImageOutset() const {
|
|
|
|
// We don't check whether there is a border-image (which is OK since
|
|
|
|
// the initial values yields 0 outset) so that we don't have to
|
|
|
|
// reflow to update overflow areas when an image loads.
|
|
|
|
nsMargin outset;
|
|
|
|
NS_FOR_CSS_SIDES(s) {
|
2019-02-14 21:03:04 +03:00
|
|
|
const auto& coord = mBorderImageOutset.Get(s);
|
2011-12-23 03:34:45 +04:00
|
|
|
nscoord value;
|
2019-02-14 21:03:04 +03:00
|
|
|
if (coord.IsLength()) {
|
2019-03-07 02:01:11 +03:00
|
|
|
value = coord.AsLength().ToAppUnits();
|
2019-02-14 21:03:04 +03:00
|
|
|
} else {
|
|
|
|
MOZ_ASSERT(coord.IsNumber());
|
2019-03-07 02:01:11 +03:00
|
|
|
value = coord.AsNumber() * mComputedBorder.Side(s);
|
2011-12-23 03:34:45 +04:00
|
|
|
}
|
|
|
|
outset.Side(s) = value;
|
|
|
|
}
|
|
|
|
return outset;
|
|
|
|
}
|
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
nsChangeHint nsStyleBorder::CalcDifference(
|
|
|
|
const nsStyleBorder& aNewData) const {
|
2016-10-13 21:41:52 +03:00
|
|
|
// FIXME: XXXbz: As in nsStylePadding::CalcDifference, many of these
|
|
|
|
// differences should not need to clear descendant intrinsics.
|
|
|
|
// FIXME: It would be good to return a weaker hint for the
|
|
|
|
// GetComputedBorder() differences (and perhaps others) that doesn't
|
|
|
|
// force reflow of all descendants, but the hint would need to force
|
|
|
|
// reflow of the frame's children (see how
|
|
|
|
// ReflowInput::InitResizeFlags initializes the inline-resize flag).
|
2016-06-21 04:47:54 +03:00
|
|
|
if (mTwipsPerPixel != aNewData.mTwipsPerPixel ||
|
|
|
|
GetComputedBorder() != aNewData.GetComputedBorder() ||
|
|
|
|
mFloatEdge != aNewData.mFloatEdge ||
|
|
|
|
mBorderImageOutset != aNewData.mBorderImageOutset ||
|
2016-07-06 08:06:13 +03:00
|
|
|
mBoxDecorationBreak != aNewData.mBoxDecorationBreak) {
|
2008-11-03 03:58:46 +03:00
|
|
|
return NS_STYLE_HINT_REFLOW;
|
2016-07-06 08:06:13 +03:00
|
|
|
}
|
2005-04-29 19:44:38 +04:00
|
|
|
|
2012-09-07 21:13:36 +04:00
|
|
|
NS_FOR_CSS_SIDES(ix) {
|
|
|
|
// See the explanation in nsChangeHint.h of
|
|
|
|
// nsChangeHint_BorderStyleNoneChange .
|
|
|
|
// Furthermore, even though we know *this* side is 0 width, just
|
Bug 1198894: Use nsChangeHint_RepaintFrame instead of NS_STYLE_HINT_VISUAL to trigger simple repaints in nsStyleStruct.cpp CalcDifference methods. r=heycam
Specifically, this makes us use nsChangeHint_RepaintFrame for changes to font decorations, border-{color,style,radius,image}, color, background-{image,color}, text-decoration-{line,color}, text-overflow
2015-09-22 02:11:51 +03:00
|
|
|
// assume a repaint hint for some other change rather than bother
|
2012-09-07 21:13:36 +04:00
|
|
|
// tracking this result through the rest of the function.
|
2016-06-21 04:47:54 +03:00
|
|
|
if (HasVisibleStyle(ix) != aNewData.HasVisibleStyle(ix)) {
|
2016-04-12 08:52:42 +03:00
|
|
|
return nsChangeHint_RepaintFrame | nsChangeHint_BorderStyleNoneChange;
|
2012-09-07 21:13:36 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-11-03 03:58:46 +03:00
|
|
|
// Note that mBorderStyle stores not only the border style but also
|
|
|
|
// color-related flags. Given that we've already done an mComputedBorder
|
Bug 1198894: Use nsChangeHint_RepaintFrame instead of NS_STYLE_HINT_VISUAL to trigger simple repaints in nsStyleStruct.cpp CalcDifference methods. r=heycam
Specifically, this makes us use nsChangeHint_RepaintFrame for changes to font decorations, border-{color,style,radius,image}, color, background-{image,color}, text-decoration-{line,color}, text-overflow
2015-09-22 02:11:51 +03:00
|
|
|
// comparison, border-style differences can only lead to a repaint hint. So
|
2008-11-03 03:58:46 +03:00
|
|
|
// it's OK to just compare the values directly -- if either the actual
|
|
|
|
// style or the color flags differ we want to repaint.
|
|
|
|
NS_FOR_CSS_SIDES(ix) {
|
2016-06-21 04:47:54 +03:00
|
|
|
if (mBorderStyle[ix] != aNewData.mBorderStyle[ix] ||
|
2018-06-05 04:24:12 +03:00
|
|
|
BorderColorFor(ix) != aNewData.BorderColorFor(ix)) {
|
Bug 1198894: Use nsChangeHint_RepaintFrame instead of NS_STYLE_HINT_VISUAL to trigger simple repaints in nsStyleStruct.cpp CalcDifference methods. r=heycam
Specifically, this makes us use nsChangeHint_RepaintFrame for changes to font decorations, border-{color,style,radius,image}, color, background-{image,color}, text-decoration-{line,color}, text-overflow
2015-09-22 02:11:51 +03:00
|
|
|
return nsChangeHint_RepaintFrame;
|
2016-07-06 08:06:13 +03:00
|
|
|
}
|
2008-11-03 03:58:46 +03:00
|
|
|
}
|
2001-12-19 14:59:31 +03:00
|
|
|
|
2018-01-15 05:36:00 +03:00
|
|
|
if (mBorderRadius != aNewData.mBorderRadius) {
|
Bug 1198894: Use nsChangeHint_RepaintFrame instead of NS_STYLE_HINT_VISUAL to trigger simple repaints in nsStyleStruct.cpp CalcDifference methods. r=heycam
Specifically, this makes us use nsChangeHint_RepaintFrame for changes to font decorations, border-{color,style,radius,image}, color, background-{image,color}, text-decoration-{line,color}, text-overflow
2015-09-22 02:11:51 +03:00
|
|
|
return nsChangeHint_RepaintFrame;
|
2016-07-06 08:06:13 +03:00
|
|
|
}
|
2008-07-26 20:14:49 +04:00
|
|
|
|
2017-04-18 10:04:35 +03:00
|
|
|
// Loading status of the border image can be accessed in main thread only
|
|
|
|
// while CalcDifference might be executed on a background thread. As a
|
|
|
|
// result, we have to check mBorderImage* fields even before border image was
|
|
|
|
// actually loaded.
|
|
|
|
if (!mBorderImageSource.IsEmpty() || !aNewData.mBorderImageSource.IsEmpty()) {
|
2016-06-21 04:47:54 +03:00
|
|
|
if (mBorderImageSource != aNewData.mBorderImageSource ||
|
|
|
|
mBorderImageRepeatH != aNewData.mBorderImageRepeatH ||
|
|
|
|
mBorderImageRepeatV != aNewData.mBorderImageRepeatV ||
|
|
|
|
mBorderImageSlice != aNewData.mBorderImageSlice ||
|
2017-01-19 11:13:02 +03:00
|
|
|
mBorderImageWidth != aNewData.mBorderImageWidth) {
|
Bug 1198894: Use nsChangeHint_RepaintFrame instead of NS_STYLE_HINT_VISUAL to trigger simple repaints in nsStyleStruct.cpp CalcDifference methods. r=heycam
Specifically, this makes us use nsChangeHint_RepaintFrame for changes to font decorations, border-{color,style,radius,image}, color, background-{image,color}, text-decoration-{line,color}, text-overflow
2015-09-22 02:11:51 +03:00
|
|
|
return nsChangeHint_RepaintFrame;
|
2016-07-06 08:06:13 +03:00
|
|
|
}
|
2008-11-03 03:58:46 +03:00
|
|
|
}
|
2001-12-19 14:59:31 +03:00
|
|
|
|
2014-09-05 07:48:43 +04:00
|
|
|
// mBorder is the specified border value. Changes to this don't
|
|
|
|
// need any change processing, since we operate on the computed
|
|
|
|
// border values instead.
|
2016-06-21 04:47:54 +03:00
|
|
|
if (mBorder != aNewData.mBorder) {
|
2014-09-05 07:48:43 +04:00
|
|
|
return nsChangeHint_NeutralChange;
|
|
|
|
}
|
|
|
|
|
2017-04-18 10:04:35 +03:00
|
|
|
// mBorderImage* fields are checked only when border-image is not 'none'.
|
2017-01-19 11:13:02 +03:00
|
|
|
if (mBorderImageSource != aNewData.mBorderImageSource ||
|
|
|
|
mBorderImageRepeatH != aNewData.mBorderImageRepeatH ||
|
|
|
|
mBorderImageRepeatV != aNewData.mBorderImageRepeatV ||
|
|
|
|
mBorderImageSlice != aNewData.mBorderImageSlice ||
|
|
|
|
mBorderImageWidth != aNewData.mBorderImageWidth) {
|
|
|
|
return nsChangeHint_NeutralChange;
|
|
|
|
}
|
|
|
|
|
2016-07-17 17:20:21 +03:00
|
|
|
return nsChangeHint(0);
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
|
|
|
|
2019-01-18 20:32:22 +03:00
|
|
|
nsStyleOutline::nsStyleOutline(const Document& aDocument)
|
2019-02-24 21:47:53 +03:00
|
|
|
: mOutlineRadius(ZeroBorderRadius()),
|
|
|
|
mOutlineWidth(kMediumBorderWidth),
|
2019-04-04 21:32:09 +03:00
|
|
|
mOutlineOffset({0.0f}),
|
2019-04-04 14:35:33 +03:00
|
|
|
mOutlineColor(StyleColor::CurrentColor()),
|
2018-11-30 08:27:28 +03:00
|
|
|
mOutlineStyle(StyleOutlineStyle::BorderStyle(StyleBorderStyle::None)),
|
2016-09-27 13:44:19 +03:00
|
|
|
mActualOutlineWidth(0),
|
2019-01-18 20:32:22 +03:00
|
|
|
mTwipsPerPixel(TwipsPerPixel(aDocument)) {
|
2009-08-07 18:38:44 +04:00
|
|
|
MOZ_COUNT_CTOR(nsStyleOutline);
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
|
|
|
|
2014-06-19 07:17:10 +04:00
|
|
|
nsStyleOutline::nsStyleOutline(const nsStyleOutline& aSrc)
|
|
|
|
: mOutlineRadius(aSrc.mOutlineRadius),
|
|
|
|
mOutlineWidth(aSrc.mOutlineWidth),
|
|
|
|
mOutlineOffset(aSrc.mOutlineOffset),
|
|
|
|
mOutlineColor(aSrc.mOutlineColor),
|
|
|
|
mOutlineStyle(aSrc.mOutlineStyle),
|
2016-09-27 13:44:19 +03:00
|
|
|
mActualOutlineWidth(aSrc.mActualOutlineWidth),
|
2014-06-19 07:17:10 +04:00
|
|
|
mTwipsPerPixel(aSrc.mTwipsPerPixel) {
|
2009-08-07 18:38:44 +04:00
|
|
|
MOZ_COUNT_CTOR(nsStyleOutline);
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
nsChangeHint nsStyleOutline::CalcDifference(
|
|
|
|
const nsStyleOutline& aNewData) const {
|
|
|
|
if (mActualOutlineWidth != aNewData.mActualOutlineWidth ||
|
|
|
|
(mActualOutlineWidth > 0 && mOutlineOffset != aNewData.mOutlineOffset)) {
|
2016-05-23 06:26:03 +03:00
|
|
|
return nsChangeHint_UpdateOverflow | nsChangeHint_SchedulePaint |
|
Bug 1364338: Force a repaint when CSS 'outline-width' or 'outline-offset' change. r=heycam
Previously, when these properties changed, we'd only send change hints to
recompute overflow areas & trigger DLBI. If the outline was always outside of
the element's border box, this old strategy was generally OK, because the
outline tweak would cause a change to the overflow areas' size, and that would
invalidate the changed area via DLBI & trigger a repaint.
However, for outlines that are *inside* of the element (via negative
'outline-offset'), these change hints were not sufficient, because tweaks to
the outline width & offset will NOT affect the size of the element's overflow
areas and will not trigger any DLBI invalidation.
So in order to correctly handle these changes, we really need to request a
repaint of the affected element, since some piece of the element may need to be
repainted even if it's not changing in size.
MozReview-Commit-ID: J4KGUHrJ09U
--HG--
extra : rebase_source : 677950d5aebdf7e90120b8fe7bb937344da42d7d
2017-05-13 04:42:10 +03:00
|
|
|
nsChangeHint_RepaintFrame;
|
2004-07-16 20:56:21 +04:00
|
|
|
}
|
2014-09-05 07:48:43 +04:00
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
if (mOutlineStyle != aNewData.mOutlineStyle ||
|
|
|
|
mOutlineColor != aNewData.mOutlineColor ||
|
|
|
|
mOutlineRadius != aNewData.mOutlineRadius) {
|
2016-05-11 07:03:34 +03:00
|
|
|
if (mActualOutlineWidth > 0) {
|
|
|
|
return nsChangeHint_RepaintFrame;
|
|
|
|
}
|
|
|
|
return nsChangeHint_NeutralChange;
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
2014-09-05 07:48:43 +04:00
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
if (mOutlineWidth != aNewData.mOutlineWidth ||
|
|
|
|
mOutlineOffset != aNewData.mOutlineOffset ||
|
|
|
|
mTwipsPerPixel != aNewData.mTwipsPerPixel) {
|
2014-09-05 07:48:43 +04:00
|
|
|
return nsChangeHint_NeutralChange;
|
|
|
|
}
|
|
|
|
|
2016-07-17 17:20:21 +03:00
|
|
|
return nsChangeHint(0);
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------
|
|
|
|
// nsStyleList
|
|
|
|
//
|
2019-01-18 20:32:22 +03:00
|
|
|
nsStyleList::nsStyleList(const Document& aDocument)
|
2019-03-25 01:13:52 +03:00
|
|
|
: mListStylePosition(NS_STYLE_LIST_STYLE_POSITION_OUTSIDE),
|
2019-05-17 02:04:31 +03:00
|
|
|
mQuotes{StyleArcSlice<StyleQuotePair>(Servo_Quotes_GetInitialValue())},
|
2019-03-25 01:13:52 +03:00
|
|
|
mMozListReversed(StyleMozListReversed::False) {
|
2009-08-07 18:38:44 +04:00
|
|
|
MOZ_COUNT_CTOR(nsStyleList);
|
2016-11-03 04:40:53 +03:00
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
|
2019-02-02 21:41:44 +03:00
|
|
|
mCounterStyle = nsGkAtoms::disc;
|
2016-04-12 08:52:40 +03:00
|
|
|
}
|
|
|
|
|
2018-09-11 18:57:15 +03:00
|
|
|
nsStyleList::~nsStyleList() { MOZ_COUNT_DTOR(nsStyleList); }
|
2016-04-12 08:52:40 +03:00
|
|
|
|
2018-09-11 18:57:15 +03:00
|
|
|
nsStyleList::nsStyleList(const nsStyleList& aSource)
|
|
|
|
: mListStylePosition(aSource.mListStylePosition),
|
|
|
|
mListStyleImage(aSource.mListStyleImage),
|
|
|
|
mCounterStyle(aSource.mCounterStyle),
|
|
|
|
mQuotes(aSource.mQuotes),
|
2019-03-25 01:13:52 +03:00
|
|
|
mImageRegion(aSource.mImageRegion),
|
|
|
|
mMozListReversed(aSource.mMozListReversed) {
|
2018-09-11 18:57:15 +03:00
|
|
|
MOZ_COUNT_CTOR(nsStyleList);
|
2016-04-12 08:52:40 +03:00
|
|
|
}
|
|
|
|
|
2019-02-04 19:03:25 +03:00
|
|
|
void nsStyleList::TriggerImageLoads(Document& aDocument,
|
|
|
|
const nsStyleList* aOldStyle) {
|
2018-09-11 18:57:15 +03:00
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
|
|
|
|
if (mListStyleImage && !mListStyleImage->IsResolved()) {
|
|
|
|
mListStyleImage->Resolve(
|
2019-02-02 21:42:25 +03:00
|
|
|
aDocument, aOldStyle ? aOldStyle->mListStyleImage.get() : nullptr);
|
2018-09-11 18:57:15 +03:00
|
|
|
}
|
2016-04-12 08:52:40 +03:00
|
|
|
}
|
|
|
|
|
2017-06-13 13:49:33 +03:00
|
|
|
nsChangeHint nsStyleList::CalcDifference(
|
2019-02-15 02:30:19 +03:00
|
|
|
const nsStyleList& aNewData, const nsStyleDisplay& aOldDisplay) const {
|
2016-04-12 08:52:40 +03:00
|
|
|
// If the quotes implementation is ever going to change we might not need
|
|
|
|
// a framechange here and a reflow should be sufficient. See bug 35768.
|
2019-05-17 02:04:31 +03:00
|
|
|
if (mQuotes != aNewData.mQuotes) {
|
2016-07-06 08:06:14 +03:00
|
|
|
return nsChangeHint_ReconstructFrame;
|
2016-04-12 08:52:40 +03:00
|
|
|
}
|
2017-06-13 13:49:33 +03:00
|
|
|
nsChangeHint hint = nsChangeHint(0);
|
|
|
|
// Only elements whose display value is list-item can be affected by
|
|
|
|
// list-style-position and list-style-type. If the old display struct
|
|
|
|
// doesn't exist, assume it isn't affected by display value at all,
|
|
|
|
// and thus these properties should not affect it either. This also
|
|
|
|
// relies on that when the display value changes from something else
|
|
|
|
// to list-item, that change itself would cause ReconstructFrame.
|
2019-02-15 02:30:19 +03:00
|
|
|
if (aOldDisplay.mDisplay == StyleDisplay::ListItem) {
|
2017-06-13 13:49:33 +03:00
|
|
|
if (mListStylePosition != aNewData.mListStylePosition) {
|
|
|
|
return nsChangeHint_ReconstructFrame;
|
|
|
|
}
|
|
|
|
if (mCounterStyle != aNewData.mCounterStyle) {
|
|
|
|
return NS_STYLE_HINT_REFLOW;
|
2014-09-20 05:43:00 +04:00
|
|
|
}
|
2017-06-13 13:49:33 +03:00
|
|
|
} else if (mListStylePosition != aNewData.mListStylePosition ||
|
|
|
|
mCounterStyle != aNewData.mCounterStyle) {
|
|
|
|
hint = nsChangeHint_NeutralChange;
|
|
|
|
}
|
2019-03-25 01:13:52 +03:00
|
|
|
// This is an internal UA-sheet property that is true only for <ol reversed>
|
|
|
|
// so hopefully it changes rarely.
|
|
|
|
if (mMozListReversed != aNewData.mMozListReversed) {
|
|
|
|
return NS_STYLE_HINT_REFLOW;
|
|
|
|
}
|
2017-06-13 13:49:33 +03:00
|
|
|
// list-style-image and -moz-image-region may affect some XUL elements
|
|
|
|
// regardless of display value, so we still need to check them.
|
|
|
|
if (!DefinitelyEqualImages(mListStyleImage, aNewData.mListStyleImage)) {
|
|
|
|
return NS_STYLE_HINT_REFLOW;
|
|
|
|
}
|
|
|
|
if (!mImageRegion.IsEqualInterior(aNewData.mImageRegion)) {
|
|
|
|
if (mImageRegion.width != aNewData.mImageRegion.width ||
|
|
|
|
mImageRegion.height != aNewData.mImageRegion.height) {
|
|
|
|
return NS_STYLE_HINT_REFLOW;
|
2016-07-06 08:06:13 +03:00
|
|
|
}
|
2017-06-13 13:49:33 +03:00
|
|
|
return NS_STYLE_HINT_VISUAL;
|
2002-11-06 10:31:27 +03:00
|
|
|
}
|
2017-06-13 13:49:33 +03:00
|
|
|
return hint;
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
|
|
|
|
2017-03-09 08:03:32 +03:00
|
|
|
already_AddRefed<nsIURI> nsStyleList::GetListStyleImageURI() const {
|
|
|
|
if (!mListStyleImage) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIURI> uri = mListStyleImage->GetImageURI();
|
|
|
|
return uri.forget();
|
|
|
|
}
|
|
|
|
|
2001-06-01 02:19:43 +04:00
|
|
|
// --------------------
|
|
|
|
// nsStyleXUL
|
|
|
|
//
|
2019-01-18 20:32:22 +03:00
|
|
|
nsStyleXUL::nsStyleXUL(const Document& aDocument)
|
2016-05-02 06:11:45 +03:00
|
|
|
: mBoxFlex(0.0f),
|
|
|
|
mBoxOrdinal(1),
|
2016-08-26 10:09:19 +03:00
|
|
|
mBoxAlign(StyleBoxAlign::Stretch),
|
2016-08-26 10:17:09 +03:00
|
|
|
mBoxDirection(StyleBoxDirection::Normal),
|
2016-08-26 10:18:41 +03:00
|
|
|
mBoxOrient(StyleBoxOrient::Horizontal),
|
2016-08-26 10:11:54 +03:00
|
|
|
mBoxPack(StyleBoxPack::Start),
|
2017-05-15 14:33:46 +03:00
|
|
|
mStackSizing(StyleStackSizing::StretchToFit) {
|
2009-08-07 18:38:44 +04:00
|
|
|
MOZ_COUNT_CTOR(nsStyleXUL);
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
|
|
|
|
2009-08-07 18:38:44 +04:00
|
|
|
nsStyleXUL::~nsStyleXUL() { MOZ_COUNT_DTOR(nsStyleXUL); }
|
2001-06-01 02:19:43 +04:00
|
|
|
|
|
|
|
nsStyleXUL::nsStyleXUL(const nsStyleXUL& aSource)
|
2014-06-19 07:17:10 +04:00
|
|
|
: mBoxFlex(aSource.mBoxFlex),
|
|
|
|
mBoxOrdinal(aSource.mBoxOrdinal),
|
|
|
|
mBoxAlign(aSource.mBoxAlign),
|
|
|
|
mBoxDirection(aSource.mBoxDirection),
|
|
|
|
mBoxOrient(aSource.mBoxOrient),
|
|
|
|
mBoxPack(aSource.mBoxPack),
|
2017-05-15 14:33:46 +03:00
|
|
|
mStackSizing(aSource.mStackSizing) {
|
2009-08-07 18:38:44 +04:00
|
|
|
MOZ_COUNT_CTOR(nsStyleXUL);
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
nsChangeHint nsStyleXUL::CalcDifference(const nsStyleXUL& aNewData) const {
|
|
|
|
if (mBoxAlign == aNewData.mBoxAlign &&
|
|
|
|
mBoxDirection == aNewData.mBoxDirection &&
|
|
|
|
mBoxFlex == aNewData.mBoxFlex && mBoxOrient == aNewData.mBoxOrient &&
|
|
|
|
mBoxPack == aNewData.mBoxPack && mBoxOrdinal == aNewData.mBoxOrdinal &&
|
2017-05-15 14:33:46 +03:00
|
|
|
mStackSizing == aNewData.mStackSizing) {
|
2016-07-17 17:20:21 +03:00
|
|
|
return nsChangeHint(0);
|
2016-07-06 08:06:13 +03:00
|
|
|
}
|
|
|
|
if (mBoxOrdinal != aNewData.mBoxOrdinal) {
|
2016-07-06 08:06:14 +03:00
|
|
|
return nsChangeHint_ReconstructFrame;
|
2016-07-06 08:06:13 +03:00
|
|
|
}
|
2001-06-01 02:19:43 +04:00
|
|
|
return NS_STYLE_HINT_REFLOW;
|
|
|
|
}
|
|
|
|
|
2004-06-17 15:57:37 +04:00
|
|
|
// --------------------
|
|
|
|
// nsStyleColumn
|
|
|
|
//
|
2016-10-25 09:25:10 +03:00
|
|
|
/* static */ const uint32_t nsStyleColumn::kMaxColumnCount;
|
2018-07-21 03:09:31 +03:00
|
|
|
/* static */ const uint32_t nsStyleColumn::kColumnCountAuto;
|
2013-05-31 19:51:43 +04:00
|
|
|
|
2019-01-18 20:32:22 +03:00
|
|
|
nsStyleColumn::nsStyleColumn(const Document& aDocument)
|
2019-04-04 21:29:57 +03:00
|
|
|
: mColumnWidth(LengthOrAuto::Auto()),
|
2019-04-04 14:35:33 +03:00
|
|
|
mColumnRuleColor(StyleColor::CurrentColor()),
|
2018-11-07 22:56:17 +03:00
|
|
|
mColumnRuleStyle(StyleBorderStyle::None),
|
2018-11-27 22:52:13 +03:00
|
|
|
mColumnRuleWidth(kMediumBorderWidth),
|
2019-01-18 20:32:22 +03:00
|
|
|
mTwipsPerPixel(TwipsPerPixel(aDocument)) {
|
2009-08-07 18:38:44 +04:00
|
|
|
MOZ_COUNT_CTOR(nsStyleColumn);
|
2004-06-17 15:57:37 +04:00
|
|
|
}
|
|
|
|
|
2016-05-02 06:11:45 +03:00
|
|
|
nsStyleColumn::~nsStyleColumn() { MOZ_COUNT_DTOR(nsStyleColumn); }
|
2004-06-17 15:57:37 +04:00
|
|
|
|
|
|
|
nsStyleColumn::nsStyleColumn(const nsStyleColumn& aSource)
|
2014-06-19 07:17:10 +04:00
|
|
|
: mColumnCount(aSource.mColumnCount),
|
|
|
|
mColumnWidth(aSource.mColumnWidth),
|
|
|
|
mColumnRuleColor(aSource.mColumnRuleColor),
|
|
|
|
mColumnRuleStyle(aSource.mColumnRuleStyle),
|
|
|
|
mColumnFill(aSource.mColumnFill),
|
2017-02-14 03:57:33 +03:00
|
|
|
mColumnSpan(aSource.mColumnSpan),
|
2014-06-19 07:17:10 +04:00
|
|
|
mColumnRuleWidth(aSource.mColumnRuleWidth),
|
|
|
|
mTwipsPerPixel(aSource.mTwipsPerPixel) {
|
2009-08-07 18:38:44 +04:00
|
|
|
MOZ_COUNT_CTOR(nsStyleColumn);
|
2004-06-17 15:57:37 +04:00
|
|
|
}
|
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
nsChangeHint nsStyleColumn::CalcDifference(
|
|
|
|
const nsStyleColumn& aNewData) const {
|
2019-04-04 21:29:57 +03:00
|
|
|
if (mColumnWidth.IsAuto() != aNewData.mColumnWidth.IsAuto() ||
|
2017-02-14 03:57:33 +03:00
|
|
|
mColumnCount != aNewData.mColumnCount ||
|
|
|
|
mColumnSpan != aNewData.mColumnSpan) {
|
2004-10-08 16:17:10 +04:00
|
|
|
// We force column count changes to do a reframe, because it's tricky to
|
|
|
|
// handle some edge cases where the column count gets smaller and content
|
|
|
|
// overflows.
|
|
|
|
// XXX not ideal
|
2016-07-06 08:06:14 +03:00
|
|
|
return nsChangeHint_ReconstructFrame;
|
2016-07-06 08:06:13 +03:00
|
|
|
}
|
2004-07-18 16:12:46 +04:00
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
if (mColumnWidth != aNewData.mColumnWidth ||
|
2016-07-06 08:06:13 +03:00
|
|
|
mColumnFill != aNewData.mColumnFill) {
|
2008-07-19 14:38:25 +04:00
|
|
|
return NS_STYLE_HINT_REFLOW;
|
2016-07-06 08:06:13 +03:00
|
|
|
}
|
2008-07-19 14:38:25 +04:00
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
if (GetComputedColumnRuleWidth() != aNewData.GetComputedColumnRuleWidth() ||
|
|
|
|
mColumnRuleStyle != aNewData.mColumnRuleStyle ||
|
2016-09-27 13:12:08 +03:00
|
|
|
mColumnRuleColor != aNewData.mColumnRuleColor) {
|
2008-07-19 14:38:25 +04:00
|
|
|
return NS_STYLE_HINT_VISUAL;
|
2016-07-06 08:06:13 +03:00
|
|
|
}
|
2004-07-18 16:12:46 +04:00
|
|
|
|
2014-09-05 07:48:43 +04:00
|
|
|
// XXX Is it right that we never check mTwipsPerPixel to return a
|
|
|
|
// non-nsChangeHint_NeutralChange hint?
|
2016-06-21 04:47:54 +03:00
|
|
|
if (mColumnRuleWidth != aNewData.mColumnRuleWidth ||
|
|
|
|
mTwipsPerPixel != aNewData.mTwipsPerPixel) {
|
2014-09-05 07:48:43 +04:00
|
|
|
return nsChangeHint_NeutralChange;
|
|
|
|
}
|
|
|
|
|
2016-07-17 17:20:21 +03:00
|
|
|
return nsChangeHint(0);
|
2004-06-17 15:57:37 +04:00
|
|
|
}
|
|
|
|
|
2001-12-12 10:59:31 +03:00
|
|
|
// --------------------
|
|
|
|
// nsStyleSVG
|
|
|
|
//
|
2019-01-18 20:32:22 +03:00
|
|
|
nsStyleSVG::nsStyleSVG(const Document& aDocument)
|
2018-12-05 21:44:05 +03:00
|
|
|
: mFill(eStyleSVGPaintType_Color), // Will be initialized to NS_RGB(0,0,0)
|
2016-05-03 12:26:28 +03:00
|
|
|
mStroke(eStyleSVGPaintType_None),
|
Bug 1552708 - Use cbindgen for URIs. r=heycam
This doesn't clean up as much as a whole, but it's a step in the right
direction. In particular, it allows us to start using simple bindings for:
* Filters
* Shapes and images, almost. Need to:
* Get rid of the complex -moz- gradient parsing (let
layout.css.simple-moz-gradient.enabled get to release).
* Counters, almost. Need to:
* Share the Attr representation with Gecko, by not using Option<>.
* Just another variant should be enough (ContentItem::{Attr,Prefixedattr},
maybe).
Which in turn allows us to remove a whole lot of bindings in followups to this.
The setup changes a bit. This also removes the double pointer I complained about
while reviewing the shared UA sheet patches. The old setup is:
```
SpecifiedUrl
* CssUrl
* Arc<CssUrlData>
* String
* UrlExtraData
* UrlValueSource
* Arc<CssUrlData>
* load id
* resolved uri
* CORS mode.
* ...
```
The new one removes the double reference to the url data via URLValue, and looks
like:
```
SpecifiedUrl
* CssUrl
* Arc<CssUrlData>
* String
* UrlExtraData
* CorsMode
* LoadData
* load id
* resolved URI
```
The LoadData is the only mutable bit that C++ can change, and is not used from
Rust. Ideally, in the future, we could just use rust-url to resolve the URL
after parsing or something, and make it all immutable. Maybe.
I've verified that this approach still works with the UA sheet patches (via the
LoadDataSource::Lazy).
The reordering of mWillChange is to avoid nsStyleDisplay from going over the
size limit. We want to split it up anyway in bug 1552587, but mBinding gains a
tag member, which means that we were having a bit of extra padding.
One thing I want to explore is to see if we can abuse rustc's non-zero
optimizations to predict the layout from C++, but that's something to explore at
some other point in time and with a lot of care and help from Michael (who sits
next to me and works on rustc ;)).
Differential Revision: https://phabricator.services.mozilla.com/D31742
2019-05-27 14:45:12 +03:00
|
|
|
mMarkerEnd(StyleUrlOrNone::None()),
|
|
|
|
mMarkerMid(StyleUrlOrNone::None()),
|
|
|
|
mMarkerStart(StyleUrlOrNone::None()),
|
2019-05-17 02:03:29 +03:00
|
|
|
mMozContextProperties{{}, {0}},
|
2019-03-02 04:09:19 +03:00
|
|
|
mStrokeDashoffset(LengthPercentage::Zero()),
|
|
|
|
mStrokeWidth(LengthPercentage::FromPixels(1.0f)),
|
2016-05-03 12:26:28 +03:00
|
|
|
mFillOpacity(1.0f),
|
|
|
|
mStrokeMiterlimit(4.0f),
|
|
|
|
mStrokeOpacity(1.0f),
|
2016-08-17 09:43:26 +03:00
|
|
|
mClipRule(StyleFillRule::Nonzero),
|
2016-05-03 12:26:28 +03:00
|
|
|
mColorInterpolation(NS_STYLE_COLOR_INTERPOLATION_SRGB),
|
|
|
|
mColorInterpolationFilters(NS_STYLE_COLOR_INTERPOLATION_LINEARRGB),
|
2016-08-17 09:43:26 +03:00
|
|
|
mFillRule(StyleFillRule::Nonzero),
|
2016-05-03 12:26:28 +03:00
|
|
|
mPaintOrder(NS_STYLE_PAINT_ORDER_NORMAL),
|
|
|
|
mShapeRendering(NS_STYLE_SHAPE_RENDERING_AUTO),
|
|
|
|
mStrokeLinecap(NS_STYLE_STROKE_LINECAP_BUTT),
|
|
|
|
mStrokeLinejoin(NS_STYLE_STROKE_LINEJOIN_MITER),
|
|
|
|
mTextAnchor(NS_STYLE_TEXT_ANCHOR_START),
|
2016-06-03 10:16:39 +03:00
|
|
|
mContextFlags(
|
|
|
|
(eStyleSVGOpacitySource_Normal << FILL_OPACITY_SOURCE_SHIFT) |
|
|
|
|
(eStyleSVGOpacitySource_Normal << STROKE_OPACITY_SOURCE_SHIFT)) {
|
2016-01-11 02:28:35 +03:00
|
|
|
MOZ_COUNT_CTOR(nsStyleSVG);
|
2016-05-03 12:26:28 +03:00
|
|
|
}
|
2016-01-11 02:28:35 +03:00
|
|
|
|
2009-08-07 18:38:44 +04:00
|
|
|
nsStyleSVG::~nsStyleSVG() { MOZ_COUNT_DTOR(nsStyleSVG); }
|
2001-12-12 10:59:31 +03:00
|
|
|
|
|
|
|
nsStyleSVG::nsStyleSVG(const nsStyleSVG& aSource)
|
2016-05-03 12:26:28 +03:00
|
|
|
: mFill(aSource.mFill),
|
|
|
|
mStroke(aSource.mStroke),
|
|
|
|
mMarkerEnd(aSource.mMarkerEnd),
|
|
|
|
mMarkerMid(aSource.mMarkerMid),
|
|
|
|
mMarkerStart(aSource.mMarkerStart),
|
2016-05-26 09:01:58 +03:00
|
|
|
mStrokeDasharray(aSource.mStrokeDasharray),
|
2019-05-17 02:03:29 +03:00
|
|
|
mMozContextProperties(aSource.mMozContextProperties),
|
2016-05-03 12:26:28 +03:00
|
|
|
mStrokeDashoffset(aSource.mStrokeDashoffset),
|
|
|
|
mStrokeWidth(aSource.mStrokeWidth),
|
|
|
|
mFillOpacity(aSource.mFillOpacity),
|
|
|
|
mStrokeMiterlimit(aSource.mStrokeMiterlimit),
|
|
|
|
mStrokeOpacity(aSource.mStrokeOpacity),
|
|
|
|
mClipRule(aSource.mClipRule),
|
|
|
|
mColorInterpolation(aSource.mColorInterpolation),
|
|
|
|
mColorInterpolationFilters(aSource.mColorInterpolationFilters),
|
|
|
|
mFillRule(aSource.mFillRule),
|
|
|
|
mPaintOrder(aSource.mPaintOrder),
|
|
|
|
mShapeRendering(aSource.mShapeRendering),
|
|
|
|
mStrokeLinecap(aSource.mStrokeLinecap),
|
|
|
|
mStrokeLinejoin(aSource.mStrokeLinejoin),
|
|
|
|
mTextAnchor(aSource.mTextAnchor),
|
2016-06-03 10:16:39 +03:00
|
|
|
mContextFlags(aSource.mContextFlags) {
|
2009-08-07 18:38:44 +04:00
|
|
|
MOZ_COUNT_CTOR(nsStyleSVG);
|
2001-12-12 10:59:31 +03:00
|
|
|
}
|
|
|
|
|
2016-06-03 18:56:54 +03:00
|
|
|
static bool PaintURIChanged(const nsStyleSVGPaint& aPaint1,
|
|
|
|
const nsStyleSVGPaint& aPaint2) {
|
2016-10-11 09:56:11 +03:00
|
|
|
if (aPaint1.Type() != aPaint2.Type()) {
|
|
|
|
return aPaint1.Type() == eStyleSVGPaintType_Server ||
|
|
|
|
aPaint2.Type() == eStyleSVGPaintType_Server;
|
2008-10-01 04:51:05 +04:00
|
|
|
}
|
2016-10-11 09:56:11 +03:00
|
|
|
return aPaint1.Type() == eStyleSVGPaintType_Server &&
|
Bug 1552708 - Use cbindgen for URIs. r=heycam
This doesn't clean up as much as a whole, but it's a step in the right
direction. In particular, it allows us to start using simple bindings for:
* Filters
* Shapes and images, almost. Need to:
* Get rid of the complex -moz- gradient parsing (let
layout.css.simple-moz-gradient.enabled get to release).
* Counters, almost. Need to:
* Share the Attr representation with Gecko, by not using Option<>.
* Just another variant should be enough (ContentItem::{Attr,Prefixedattr},
maybe).
Which in turn allows us to remove a whole lot of bindings in followups to this.
The setup changes a bit. This also removes the double pointer I complained about
while reviewing the shared UA sheet patches. The old setup is:
```
SpecifiedUrl
* CssUrl
* Arc<CssUrlData>
* String
* UrlExtraData
* UrlValueSource
* Arc<CssUrlData>
* load id
* resolved uri
* CORS mode.
* ...
```
The new one removes the double reference to the url data via URLValue, and looks
like:
```
SpecifiedUrl
* CssUrl
* Arc<CssUrlData>
* String
* UrlExtraData
* CorsMode
* LoadData
* load id
* resolved URI
```
The LoadData is the only mutable bit that C++ can change, and is not used from
Rust. Ideally, in the future, we could just use rust-url to resolve the URL
after parsing or something, and make it all immutable. Maybe.
I've verified that this approach still works with the UA sheet patches (via the
LoadDataSource::Lazy).
The reordering of mWillChange is to avoid nsStyleDisplay from going over the
size limit. We want to split it up anyway in bug 1552587, but mBinding gains a
tag member, which means that we were having a bit of extra padding.
One thing I want to explore is to see if we can abuse rustc's non-zero
optimizations to predict the layout from C++, but that's something to explore at
some other point in time and with a lot of care and help from Michael (who sits
next to me and works on rustc ;)).
Differential Revision: https://phabricator.services.mozilla.com/D31742
2019-05-27 14:45:12 +03:00
|
|
|
aPaint1.GetPaintServer() != aPaint2.GetPaintServer();
|
2008-10-01 04:51:05 +04:00
|
|
|
}
|
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
nsChangeHint nsStyleSVG::CalcDifference(const nsStyleSVG& aNewData) const {
|
2008-10-01 04:51:05 +04:00
|
|
|
nsChangeHint hint = nsChangeHint(0);
|
|
|
|
|
Bug 1552708 - Use cbindgen for URIs. r=heycam
This doesn't clean up as much as a whole, but it's a step in the right
direction. In particular, it allows us to start using simple bindings for:
* Filters
* Shapes and images, almost. Need to:
* Get rid of the complex -moz- gradient parsing (let
layout.css.simple-moz-gradient.enabled get to release).
* Counters, almost. Need to:
* Share the Attr representation with Gecko, by not using Option<>.
* Just another variant should be enough (ContentItem::{Attr,Prefixedattr},
maybe).
Which in turn allows us to remove a whole lot of bindings in followups to this.
The setup changes a bit. This also removes the double pointer I complained about
while reviewing the shared UA sheet patches. The old setup is:
```
SpecifiedUrl
* CssUrl
* Arc<CssUrlData>
* String
* UrlExtraData
* UrlValueSource
* Arc<CssUrlData>
* load id
* resolved uri
* CORS mode.
* ...
```
The new one removes the double reference to the url data via URLValue, and looks
like:
```
SpecifiedUrl
* CssUrl
* Arc<CssUrlData>
* String
* UrlExtraData
* CorsMode
* LoadData
* load id
* resolved URI
```
The LoadData is the only mutable bit that C++ can change, and is not used from
Rust. Ideally, in the future, we could just use rust-url to resolve the URL
after parsing or something, and make it all immutable. Maybe.
I've verified that this approach still works with the UA sheet patches (via the
LoadDataSource::Lazy).
The reordering of mWillChange is to avoid nsStyleDisplay from going over the
size limit. We want to split it up anyway in bug 1552587, but mBinding gains a
tag member, which means that we were having a bit of extra padding.
One thing I want to explore is to see if we can abuse rustc's non-zero
optimizations to predict the layout from C++, but that's something to explore at
some other point in time and with a lot of care and help from Michael (who sits
next to me and works on rustc ;)).
Differential Revision: https://phabricator.services.mozilla.com/D31742
2019-05-27 14:45:12 +03:00
|
|
|
if (mMarkerEnd != aNewData.mMarkerEnd || mMarkerMid != aNewData.mMarkerMid ||
|
|
|
|
mMarkerStart != aNewData.mMarkerStart) {
|
2016-12-18 14:11:47 +03:00
|
|
|
// Markers currently contribute to SVGGeometryFrame::mRect,
|
2013-05-24 21:31:33 +04:00
|
|
|
// so we need a reflow as well as a repaint. No intrinsic sizes need
|
|
|
|
// to change, so nsChangeHint_NeedReflow is sufficient.
|
2016-05-23 06:26:03 +03:00
|
|
|
return nsChangeHint_UpdateEffects | nsChangeHint_NeedReflow |
|
|
|
|
nsChangeHint_NeedDirtyReflow | // XXX remove me: bug 876085
|
|
|
|
nsChangeHint_RepaintFrame;
|
2009-01-22 04:02:40 +03:00
|
|
|
}
|
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
if (mFill != aNewData.mFill || mStroke != aNewData.mStroke ||
|
|
|
|
mFillOpacity != aNewData.mFillOpacity ||
|
|
|
|
mStrokeOpacity != aNewData.mStrokeOpacity) {
|
2016-05-23 06:26:03 +03:00
|
|
|
hint |= nsChangeHint_RepaintFrame;
|
2016-06-21 04:47:54 +03:00
|
|
|
if (HasStroke() != aNewData.HasStroke() ||
|
|
|
|
(!HasStroke() && HasFill() != aNewData.HasFill())) {
|
2013-11-23 17:32:21 +04:00
|
|
|
// Frame bounds and overflow rects depend on whether we "have" fill or
|
|
|
|
// stroke. Whether we have stroke or not just changed, or else we have no
|
|
|
|
// stroke (in which case whether we have fill or not is significant to
|
|
|
|
// frame bounds) and whether we have fill or not just changed. In either
|
|
|
|
// case we need to reflow so the frame rect is updated.
|
2016-12-18 14:11:47 +03:00
|
|
|
// XXXperf this is a waste on non SVGGeometryFrames.
|
2016-05-23 06:26:03 +03:00
|
|
|
hint |= nsChangeHint_NeedReflow |
|
|
|
|
nsChangeHint_NeedDirtyReflow; // XXX remove me: bug 876085
|
2013-11-23 17:32:21 +04:00
|
|
|
}
|
2016-06-21 04:47:54 +03:00
|
|
|
if (PaintURIChanged(mFill, aNewData.mFill) ||
|
|
|
|
PaintURIChanged(mStroke, aNewData.mStroke)) {
|
2016-05-23 06:26:03 +03:00
|
|
|
hint |= nsChangeHint_UpdateEffects;
|
2008-10-01 04:51:05 +04:00
|
|
|
}
|
2013-05-24 21:31:33 +04:00
|
|
|
}
|
|
|
|
|
2016-12-18 14:11:47 +03:00
|
|
|
// Stroke currently contributes to SVGGeometryFrame::mRect, so
|
2013-05-24 21:31:33 +04:00
|
|
|
// we need a reflow here. No intrinsic sizes need to change, so
|
|
|
|
// nsChangeHint_NeedReflow is sufficient.
|
2016-12-18 14:11:47 +03:00
|
|
|
// Note that stroke-dashoffset does not affect SVGGeometryFrame::mRect.
|
2016-04-12 08:52:41 +03:00
|
|
|
// text-anchor changes also require a reflow since it changes frames' rects.
|
2016-06-21 04:47:54 +03:00
|
|
|
if (mStrokeWidth != aNewData.mStrokeWidth ||
|
|
|
|
mStrokeMiterlimit != aNewData.mStrokeMiterlimit ||
|
|
|
|
mStrokeLinecap != aNewData.mStrokeLinecap ||
|
|
|
|
mStrokeLinejoin != aNewData.mStrokeLinejoin ||
|
|
|
|
mTextAnchor != aNewData.mTextAnchor) {
|
2016-05-23 06:26:03 +03:00
|
|
|
return hint | nsChangeHint_NeedReflow |
|
|
|
|
nsChangeHint_NeedDirtyReflow | // XXX remove me: bug 876085
|
|
|
|
nsChangeHint_RepaintFrame;
|
2008-10-01 04:51:05 +04:00
|
|
|
}
|
2007-01-08 19:48:56 +03:00
|
|
|
|
2013-05-24 21:31:33 +04:00
|
|
|
if (hint & nsChangeHint_RepaintFrame) {
|
|
|
|
return hint; // we don't add anything else below
|
|
|
|
}
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
if (mStrokeDashoffset != aNewData.mStrokeDashoffset ||
|
|
|
|
mClipRule != aNewData.mClipRule ||
|
|
|
|
mColorInterpolation != aNewData.mColorInterpolation ||
|
|
|
|
mColorInterpolationFilters != aNewData.mColorInterpolationFilters ||
|
|
|
|
mFillRule != aNewData.mFillRule || mPaintOrder != aNewData.mPaintOrder ||
|
|
|
|
mShapeRendering != aNewData.mShapeRendering ||
|
|
|
|
mStrokeDasharray != aNewData.mStrokeDasharray ||
|
2017-04-11 23:38:10 +03:00
|
|
|
mContextFlags != aNewData.mContextFlags ||
|
2019-05-17 02:03:29 +03:00
|
|
|
mMozContextProperties.bits != aNewData.mMozContextProperties.bits) {
|
2016-05-23 06:26:03 +03:00
|
|
|
return hint | nsChangeHint_RepaintFrame;
|
2008-10-01 04:51:05 +04:00
|
|
|
}
|
2001-12-12 10:59:31 +03:00
|
|
|
|
2017-04-11 23:38:10 +03:00
|
|
|
if (!hint) {
|
2019-05-17 02:03:29 +03:00
|
|
|
if (mMozContextProperties.idents != aNewData.mMozContextProperties.idents) {
|
2017-04-11 23:38:10 +03:00
|
|
|
hint = nsChangeHint_NeutralChange;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-10-01 04:51:05 +04:00
|
|
|
return hint;
|
2001-12-12 10:59:31 +03:00
|
|
|
}
|
|
|
|
|
2017-09-27 06:32:38 +03:00
|
|
|
// --------------------
|
|
|
|
// StyleShapeSource
|
2018-08-07 10:56:01 +03:00
|
|
|
StyleShapeSource::StyleShapeSource() : mBasicShape() {}
|
2017-09-27 06:32:38 +03:00
|
|
|
|
|
|
|
StyleShapeSource::StyleShapeSource(const StyleShapeSource& aSource) {
|
2017-09-29 11:24:23 +03:00
|
|
|
DoCopy(aSource);
|
2017-09-27 06:32:38 +03:00
|
|
|
}
|
|
|
|
|
2018-08-07 10:56:01 +03:00
|
|
|
StyleShapeSource::~StyleShapeSource() { DoDestroy(); }
|
|
|
|
|
2017-09-27 06:32:38 +03:00
|
|
|
StyleShapeSource& StyleShapeSource::operator=(const StyleShapeSource& aOther) {
|
2017-09-29 11:24:23 +03:00
|
|
|
if (this != &aOther) {
|
|
|
|
DoCopy(aOther);
|
2017-09-27 06:32:38 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2017-09-29 09:36:35 +03:00
|
|
|
bool StyleShapeSource::operator==(const StyleShapeSource& aOther) const {
|
|
|
|
if (mType != aOther.mType) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2017-11-17 11:34:37 +03:00
|
|
|
switch (mType) {
|
|
|
|
case StyleShapeSourceType::None:
|
|
|
|
return true;
|
|
|
|
|
|
|
|
case StyleShapeSourceType::Image:
|
|
|
|
return *mShapeImage == *aOther.mShapeImage;
|
|
|
|
|
|
|
|
case StyleShapeSourceType::Shape:
|
|
|
|
return *mBasicShape == *aOther.mBasicShape &&
|
|
|
|
mReferenceBox == aOther.mReferenceBox;
|
|
|
|
|
|
|
|
case StyleShapeSourceType::Box:
|
|
|
|
return mReferenceBox == aOther.mReferenceBox;
|
2018-07-07 00:31:52 +03:00
|
|
|
|
|
|
|
case StyleShapeSourceType::Path:
|
|
|
|
return *mSVGPath == *aOther.mSVGPath;
|
2017-09-29 09:36:35 +03:00
|
|
|
}
|
|
|
|
|
2017-11-17 11:34:37 +03:00
|
|
|
MOZ_ASSERT_UNREACHABLE("Unexpected shape source type!");
|
2017-09-29 09:36:35 +03:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-11-17 11:34:37 +03:00
|
|
|
void StyleShapeSource::SetShapeImage(UniquePtr<nsStyleImage> aShapeImage) {
|
|
|
|
MOZ_ASSERT(aShapeImage);
|
2018-08-07 10:56:01 +03:00
|
|
|
DoDestroy();
|
|
|
|
new (&mShapeImage) UniquePtr<nsStyleImage>(std::move(aShapeImage));
|
2017-11-17 11:34:37 +03:00
|
|
|
mType = StyleShapeSourceType::Image;
|
|
|
|
}
|
|
|
|
|
2018-01-25 09:56:43 +03:00
|
|
|
imgIRequest* StyleShapeSource::GetShapeImageData() const {
|
|
|
|
if (mType != StyleShapeSourceType::Image) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
if (mShapeImage->GetType() != eStyleImageType_Image) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
return mShapeImage->GetImageData();
|
|
|
|
}
|
|
|
|
|
2017-09-25 13:50:24 +03:00
|
|
|
void StyleShapeSource::SetBasicShape(UniquePtr<StyleBasicShape> aBasicShape,
|
2017-09-27 06:32:38 +03:00
|
|
|
StyleGeometryBox aReferenceBox) {
|
2017-11-17 11:34:37 +03:00
|
|
|
MOZ_ASSERT(aBasicShape);
|
2018-08-07 10:56:01 +03:00
|
|
|
DoDestroy();
|
|
|
|
new (&mBasicShape) UniquePtr<StyleBasicShape>(std::move(aBasicShape));
|
2017-09-27 06:32:38 +03:00
|
|
|
mReferenceBox = aReferenceBox;
|
|
|
|
mType = StyleShapeSourceType::Shape;
|
|
|
|
}
|
|
|
|
|
2018-07-07 00:31:52 +03:00
|
|
|
void StyleShapeSource::SetPath(UniquePtr<StyleSVGPath> aPath) {
|
|
|
|
MOZ_ASSERT(aPath);
|
|
|
|
DoDestroy();
|
|
|
|
new (&mSVGPath) UniquePtr<StyleSVGPath>(std::move(aPath));
|
|
|
|
mType = StyleShapeSourceType::Path;
|
|
|
|
}
|
|
|
|
|
2019-02-04 19:03:25 +03:00
|
|
|
void StyleShapeSource::TriggerImageLoads(
|
|
|
|
Document& aDocument, const StyleShapeSource* aOldShapeSource) {
|
2018-11-02 21:19:06 +03:00
|
|
|
if (GetType() != StyleShapeSourceType::Image) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto* oldShapeImage = (aOldShapeSource && aOldShapeSource->GetType() ==
|
|
|
|
StyleShapeSourceType::Image)
|
|
|
|
? &aOldShapeSource->ShapeImage()
|
|
|
|
: nullptr;
|
2019-02-02 21:42:25 +03:00
|
|
|
mShapeImage->ResolveImage(aDocument, oldShapeImage);
|
2018-11-02 21:19:06 +03:00
|
|
|
}
|
|
|
|
|
2017-09-27 06:32:38 +03:00
|
|
|
void StyleShapeSource::SetReferenceBox(StyleGeometryBox aReferenceBox) {
|
2018-08-07 10:56:01 +03:00
|
|
|
DoDestroy();
|
2017-09-27 06:32:38 +03:00
|
|
|
mReferenceBox = aReferenceBox;
|
|
|
|
mType = StyleShapeSourceType::Box;
|
|
|
|
}
|
|
|
|
|
2017-09-29 11:24:23 +03:00
|
|
|
void StyleShapeSource::DoCopy(const StyleShapeSource& aOther) {
|
|
|
|
switch (aOther.mType) {
|
|
|
|
case StyleShapeSourceType::None:
|
|
|
|
mReferenceBox = StyleGeometryBox::NoBox;
|
|
|
|
mType = StyleShapeSourceType::None;
|
|
|
|
break;
|
|
|
|
|
2017-11-17 11:34:37 +03:00
|
|
|
case StyleShapeSourceType::Image:
|
2018-11-02 21:19:06 +03:00
|
|
|
SetShapeImage(MakeUnique<nsStyleImage>(aOther.ShapeImage()));
|
2017-11-17 11:34:37 +03:00
|
|
|
break;
|
|
|
|
|
2019-05-09 14:24:57 +03:00
|
|
|
case StyleShapeSourceType::Shape: {
|
2019-05-22 00:07:55 +03:00
|
|
|
UniquePtr<StyleBasicShape> shape(
|
|
|
|
Servo_CloneBasicShape(&aOther.BasicShape()));
|
2019-05-09 14:24:57 +03:00
|
|
|
// TODO(emilio): This could be a copy-ctor call like above if we teach
|
|
|
|
// cbindgen to generate copy-constructors for tagged unions.
|
|
|
|
SetBasicShape(std::move(shape), aOther.GetReferenceBox());
|
2017-09-29 11:24:23 +03:00
|
|
|
break;
|
2019-05-09 14:24:57 +03:00
|
|
|
}
|
2017-09-29 11:24:23 +03:00
|
|
|
|
|
|
|
case StyleShapeSourceType::Box:
|
|
|
|
SetReferenceBox(aOther.GetReferenceBox());
|
|
|
|
break;
|
2018-07-07 00:31:52 +03:00
|
|
|
|
|
|
|
case StyleShapeSourceType::Path:
|
2018-11-02 21:19:06 +03:00
|
|
|
SetPath(MakeUnique<StyleSVGPath>(aOther.Path()));
|
2018-07-07 00:31:52 +03:00
|
|
|
break;
|
2017-09-29 11:24:23 +03:00
|
|
|
}
|
2017-09-27 06:32:38 +03:00
|
|
|
}
|
|
|
|
|
2018-08-07 10:56:01 +03:00
|
|
|
void StyleShapeSource::DoDestroy() {
|
|
|
|
switch (mType) {
|
|
|
|
case StyleShapeSourceType::Shape:
|
|
|
|
mBasicShape.~UniquePtr<StyleBasicShape>();
|
|
|
|
break;
|
|
|
|
case StyleShapeSourceType::Image:
|
|
|
|
mShapeImage.~UniquePtr<nsStyleImage>();
|
|
|
|
break;
|
2018-07-07 00:31:52 +03:00
|
|
|
case StyleShapeSourceType::Path:
|
|
|
|
mSVGPath.~UniquePtr<StyleSVGPath>();
|
|
|
|
break;
|
2018-08-07 10:56:01 +03:00
|
|
|
case StyleShapeSourceType::None:
|
|
|
|
case StyleShapeSourceType::Box:
|
|
|
|
// Not a union type, so do nothing.
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
mType = StyleShapeSourceType::None;
|
|
|
|
}
|
|
|
|
|
Landing of SVG_20020806_BRANCH, Bug 182533. Refactoring of SVG backend, new GDI+ and Libart rendering
backends, text support on Windows (GDI+), rudimentary text support on Linux (libart/freetype2), presentation
attributes, lots of bug fixes (see bug 182533 for dependency list).
Not part of default build; code is #ifdef'ed out.
r=sicking, sr=jst for dom and htmlparser changes
r=bsmedberg, sr=tor for config changes
r=dbaron, sr=bzbarsky for content and layout changes
r=tor, sr=bzbarsky for gfx changes
2004-02-07 15:39:26 +03:00
|
|
|
// --------------------
|
|
|
|
// nsStyleSVGReset
|
|
|
|
//
|
2019-01-18 20:32:22 +03:00
|
|
|
nsStyleSVGReset::nsStyleSVGReset(const Document& aDocument)
|
2019-05-16 16:21:19 +03:00
|
|
|
: mX(LengthPercentage::Zero()),
|
|
|
|
mY(LengthPercentage::Zero()),
|
|
|
|
mCx(LengthPercentage::Zero()),
|
|
|
|
mCy(LengthPercentage::Zero()),
|
|
|
|
mRx(NonNegativeLengthPercentageOrAuto::Auto()),
|
|
|
|
mRy(NonNegativeLengthPercentageOrAuto::Auto()),
|
|
|
|
mR(NonNegativeLengthPercentage::Zero()),
|
|
|
|
mMask(nsStyleImageLayers::LayerType::Mask),
|
2019-04-04 14:35:33 +03:00
|
|
|
mStopColor(StyleColor::Black()),
|
|
|
|
mFloodColor(StyleColor::Black()),
|
|
|
|
mLightingColor(StyleColor::White()),
|
2016-05-03 12:26:28 +03:00
|
|
|
mStopOpacity(1.0f),
|
|
|
|
mFloodOpacity(1.0f),
|
|
|
|
mDominantBaseline(NS_STYLE_DOMINANT_BASELINE_AUTO),
|
|
|
|
mVectorEffect(NS_STYLE_VECTOR_EFFECT_NONE),
|
|
|
|
mMaskType(NS_STYLE_MASK_TYPE_LUMINANCE) {
|
2016-01-11 02:28:35 +03:00
|
|
|
MOZ_COUNT_CTOR(nsStyleSVGReset);
|
|
|
|
}
|
|
|
|
|
|
|
|
nsStyleSVGReset::~nsStyleSVGReset() { MOZ_COUNT_DTOR(nsStyleSVGReset); }
|
Landing of SVG_20020806_BRANCH, Bug 182533. Refactoring of SVG backend, new GDI+ and Libart rendering
backends, text support on Windows (GDI+), rudimentary text support on Linux (libart/freetype2), presentation
attributes, lots of bug fixes (see bug 182533 for dependency list).
Not part of default build; code is #ifdef'ed out.
r=sicking, sr=jst for dom and htmlparser changes
r=bsmedberg, sr=tor for config changes
r=dbaron, sr=bzbarsky for content and layout changes
r=tor, sr=bzbarsky for gfx changes
2004-02-07 15:39:26 +03:00
|
|
|
|
|
|
|
nsStyleSVGReset::nsStyleSVGReset(const nsStyleSVGReset& aSource)
|
2019-05-16 16:21:19 +03:00
|
|
|
: mX(aSource.mX),
|
|
|
|
mY(aSource.mY),
|
|
|
|
mCx(aSource.mCx),
|
|
|
|
mCy(aSource.mCy),
|
|
|
|
mRx(aSource.mRx),
|
|
|
|
mRy(aSource.mRy),
|
|
|
|
mR(aSource.mR),
|
|
|
|
mMask(aSource.mMask),
|
2016-05-03 12:26:28 +03:00
|
|
|
mClipPath(aSource.mClipPath),
|
|
|
|
mStopColor(aSource.mStopColor),
|
|
|
|
mFloodColor(aSource.mFloodColor),
|
|
|
|
mLightingColor(aSource.mLightingColor),
|
|
|
|
mStopOpacity(aSource.mStopOpacity),
|
|
|
|
mFloodOpacity(aSource.mFloodOpacity),
|
|
|
|
mDominantBaseline(aSource.mDominantBaseline),
|
|
|
|
mVectorEffect(aSource.mVectorEffect),
|
|
|
|
mMaskType(aSource.mMaskType) {
|
2009-08-07 18:38:44 +04:00
|
|
|
MOZ_COUNT_CTOR(nsStyleSVGReset);
|
Landing of SVG_20020806_BRANCH, Bug 182533. Refactoring of SVG backend, new GDI+ and Libart rendering
backends, text support on Windows (GDI+), rudimentary text support on Linux (libart/freetype2), presentation
attributes, lots of bug fixes (see bug 182533 for dependency list).
Not part of default build; code is #ifdef'ed out.
r=sicking, sr=jst for dom and htmlparser changes
r=bsmedberg, sr=tor for config changes
r=dbaron, sr=bzbarsky for content and layout changes
r=tor, sr=bzbarsky for gfx changes
2004-02-07 15:39:26 +03:00
|
|
|
}
|
|
|
|
|
2019-02-04 19:03:25 +03:00
|
|
|
void nsStyleSVGReset::TriggerImageLoads(Document& aDocument,
|
|
|
|
const nsStyleSVGReset* aOldStyle) {
|
2016-11-02 11:58:32 +03:00
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
2019-05-22 14:34:23 +03:00
|
|
|
// NOTE(emilio): we intentionally don't call TriggerImageLoads for clip-path.
|
2016-11-02 11:58:32 +03:00
|
|
|
|
2017-07-26 06:21:30 +03:00
|
|
|
NS_FOR_VISIBLE_IMAGE_LAYERS_BACK_TO_FRONT(i, mMask) {
|
|
|
|
nsStyleImage& image = mMask.mLayers[i].mImage;
|
|
|
|
if (image.GetType() == eStyleImageType_Image) {
|
2018-11-02 21:19:06 +03:00
|
|
|
const auto* url = image.GetURLValue();
|
2018-09-04 02:35:56 +03:00
|
|
|
// If the url is a local ref, it must be a <mask-resource>, so we don't
|
|
|
|
// need to resolve the style image.
|
|
|
|
if (url->IsLocalRef()) {
|
|
|
|
continue;
|
2017-07-26 06:21:30 +03:00
|
|
|
}
|
2018-09-04 02:35:56 +03:00
|
|
|
#if 0
|
|
|
|
// XXX The old style system also checks whether this is a reference to
|
|
|
|
// the current document with reference, but it doesn't seem to be a
|
|
|
|
// behavior mentioned anywhere, so we comment out the code for now.
|
|
|
|
nsIURI* docURI = aPresContext->Document()->GetDocumentURI();
|
|
|
|
if (url->EqualsExceptRef(docURI)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// Otherwise, we may need the image even if it has a reference, in case
|
|
|
|
// the referenced element isn't a valid SVG <mask> element.
|
|
|
|
const nsStyleImage* oldImage =
|
|
|
|
(aOldStyle && aOldStyle->mMask.mLayers.Length() > i)
|
|
|
|
? &aOldStyle->mMask.mLayers[i].mImage
|
|
|
|
: nullptr;
|
|
|
|
|
2019-02-02 21:42:25 +03:00
|
|
|
image.ResolveImage(aDocument, oldImage);
|
2017-07-26 06:21:30 +03:00
|
|
|
}
|
|
|
|
}
|
2016-11-02 11:58:32 +03:00
|
|
|
}
|
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
nsChangeHint nsStyleSVGReset::CalcDifference(
|
|
|
|
const nsStyleSVGReset& aNewData) const {
|
2008-08-06 04:55:07 +04:00
|
|
|
nsChangeHint hint = nsChangeHint(0);
|
|
|
|
|
2019-05-16 16:21:19 +03:00
|
|
|
if (mX != aNewData.mX || mY != aNewData.mY || mCx != aNewData.mCx ||
|
|
|
|
mCy != aNewData.mCy || mR != aNewData.mR || mRx != aNewData.mRx ||
|
|
|
|
mRy != aNewData.mRy) {
|
|
|
|
hint |= nsChangeHint_InvalidateRenderingObservers | nsChangeHint_NeedReflow;
|
|
|
|
}
|
|
|
|
|
2017-09-29 09:36:35 +03:00
|
|
|
if (mClipPath != aNewData.mClipPath) {
|
2016-05-23 06:26:03 +03:00
|
|
|
hint |= nsChangeHint_UpdateEffects | nsChangeHint_RepaintFrame;
|
2013-05-24 21:31:33 +04:00
|
|
|
}
|
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
if (mDominantBaseline != aNewData.mDominantBaseline) {
|
2013-05-24 21:31:33 +04:00
|
|
|
// XXXjwatt: why NS_STYLE_HINT_REFLOW? Isn't that excessive?
|
2016-05-23 06:26:03 +03:00
|
|
|
hint |= NS_STYLE_HINT_REFLOW;
|
2016-06-21 04:47:54 +03:00
|
|
|
} else if (mVectorEffect != aNewData.mVectorEffect) {
|
2016-12-18 14:11:47 +03:00
|
|
|
// Stroke currently affects SVGGeometryFrame::mRect, and
|
2013-05-24 21:31:33 +04:00
|
|
|
// vector-effect affect stroke. As a result we need to reflow if
|
2016-12-18 14:11:47 +03:00
|
|
|
// vector-effect changes in order to have SVGGeometryFrame::
|
2013-05-24 21:31:33 +04:00
|
|
|
// ReflowSVG called to update its mRect. No intrinsic sizes need
|
|
|
|
// to change so nsChangeHint_NeedReflow is sufficient.
|
2016-05-23 06:26:03 +03:00
|
|
|
hint |= nsChangeHint_NeedReflow |
|
|
|
|
nsChangeHint_NeedDirtyReflow | // XXX remove me: bug 876085
|
|
|
|
nsChangeHint_RepaintFrame;
|
2016-06-21 04:47:54 +03:00
|
|
|
} else if (mStopColor != aNewData.mStopColor ||
|
|
|
|
mFloodColor != aNewData.mFloodColor ||
|
|
|
|
mLightingColor != aNewData.mLightingColor ||
|
|
|
|
mStopOpacity != aNewData.mStopOpacity ||
|
|
|
|
mFloodOpacity != aNewData.mFloodOpacity ||
|
|
|
|
mMaskType != aNewData.mMaskType) {
|
2016-05-23 06:26:03 +03:00
|
|
|
hint |= nsChangeHint_RepaintFrame;
|
2013-05-24 21:31:33 +04:00
|
|
|
}
|
2008-08-06 04:55:07 +04:00
|
|
|
|
2016-09-22 13:24:52 +03:00
|
|
|
hint |=
|
|
|
|
mMask.CalcDifference(aNewData.mMask, nsStyleImageLayers::LayerType::Mask);
|
2016-01-28 08:28:00 +03:00
|
|
|
|
2008-08-06 04:55:07 +04:00
|
|
|
return hint;
|
Landing of SVG_20020806_BRANCH, Bug 182533. Refactoring of SVG backend, new GDI+ and Libart rendering
backends, text support on Windows (GDI+), rudimentary text support on Linux (libart/freetype2), presentation
attributes, lots of bug fixes (see bug 182533 for dependency list).
Not part of default build; code is #ifdef'ed out.
r=sicking, sr=jst for dom and htmlparser changes
r=bsmedberg, sr=tor for config changes
r=dbaron, sr=bzbarsky for content and layout changes
r=tor, sr=bzbarsky for gfx changes
2004-02-07 15:39:26 +03:00
|
|
|
}
|
|
|
|
|
2017-03-07 08:43:21 +03:00
|
|
|
bool nsStyleSVGReset::HasMask() const {
|
|
|
|
for (uint32_t i = 0; i < mMask.mImageCount; i++) {
|
2017-03-30 20:50:21 +03:00
|
|
|
if (!mMask.mLayers[i].mImage.IsEmpty()) {
|
2017-03-07 08:43:21 +03:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2004-10-15 03:02:53 +04:00
|
|
|
// nsStyleSVGPaint implementation
|
2016-05-03 12:26:27 +03:00
|
|
|
nsStyleSVGPaint::nsStyleSVGPaint(nsStyleSVGPaintType aType)
|
2019-04-04 14:35:33 +03:00
|
|
|
: mPaint(StyleColor::Black()),
|
2018-06-27 10:07:37 +03:00
|
|
|
mType(aType),
|
2017-04-29 16:03:20 +03:00
|
|
|
mFallbackType(eStyleSVGFallbackType_NotSet),
|
2019-04-04 14:35:33 +03:00
|
|
|
mFallbackColor(StyleColor::Black()) {
|
2016-10-11 09:56:11 +03:00
|
|
|
MOZ_ASSERT(aType == nsStyleSVGPaintType(0) ||
|
|
|
|
aType == eStyleSVGPaintType_None ||
|
|
|
|
aType == eStyleSVGPaintType_Color);
|
2016-05-03 12:26:27 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
nsStyleSVGPaint::nsStyleSVGPaint(const nsStyleSVGPaint& aSource)
|
2016-10-11 09:56:11 +03:00
|
|
|
: nsStyleSVGPaint(nsStyleSVGPaintType(0)) {
|
|
|
|
Assign(aSource);
|
2007-10-19 19:36:15 +04:00
|
|
|
}
|
|
|
|
|
2016-05-03 12:26:27 +03:00
|
|
|
nsStyleSVGPaint::~nsStyleSVGPaint() { Reset(); }
|
|
|
|
|
|
|
|
void nsStyleSVGPaint::Reset() {
|
2016-10-11 09:56:11 +03:00
|
|
|
switch (mType) {
|
|
|
|
case eStyleSVGPaintType_None:
|
|
|
|
break;
|
|
|
|
case eStyleSVGPaintType_Color:
|
2019-04-04 14:35:33 +03:00
|
|
|
mPaint.mColor = StyleColor::Black();
|
2016-10-11 09:56:11 +03:00
|
|
|
break;
|
|
|
|
case eStyleSVGPaintType_Server:
|
Bug 1552708 - Use cbindgen for URIs. r=heycam
This doesn't clean up as much as a whole, but it's a step in the right
direction. In particular, it allows us to start using simple bindings for:
* Filters
* Shapes and images, almost. Need to:
* Get rid of the complex -moz- gradient parsing (let
layout.css.simple-moz-gradient.enabled get to release).
* Counters, almost. Need to:
* Share the Attr representation with Gecko, by not using Option<>.
* Just another variant should be enough (ContentItem::{Attr,Prefixedattr},
maybe).
Which in turn allows us to remove a whole lot of bindings in followups to this.
The setup changes a bit. This also removes the double pointer I complained about
while reviewing the shared UA sheet patches. The old setup is:
```
SpecifiedUrl
* CssUrl
* Arc<CssUrlData>
* String
* UrlExtraData
* UrlValueSource
* Arc<CssUrlData>
* load id
* resolved uri
* CORS mode.
* ...
```
The new one removes the double reference to the url data via URLValue, and looks
like:
```
SpecifiedUrl
* CssUrl
* Arc<CssUrlData>
* String
* UrlExtraData
* CorsMode
* LoadData
* load id
* resolved URI
```
The LoadData is the only mutable bit that C++ can change, and is not used from
Rust. Ideally, in the future, we could just use rust-url to resolve the URL
after parsing or something, and make it all immutable. Maybe.
I've verified that this approach still works with the UA sheet patches (via the
LoadDataSource::Lazy).
The reordering of mWillChange is to avoid nsStyleDisplay from going over the
size limit. We want to split it up anyway in bug 1552587, but mBinding gains a
tag member, which means that we were having a bit of extra padding.
One thing I want to explore is to see if we can abuse rustc's non-zero
optimizations to predict the layout from C++, but that's something to explore at
some other point in time and with a lot of care and help from Michael (who sits
next to me and works on rustc ;)).
Differential Revision: https://phabricator.services.mozilla.com/D31742
2019-05-27 14:45:12 +03:00
|
|
|
mPaint.mPaintServer.~StyleComputedUrl();
|
2016-10-11 09:56:11 +03:00
|
|
|
MOZ_FALLTHROUGH;
|
|
|
|
case eStyleSVGPaintType_ContextFill:
|
|
|
|
case eStyleSVGPaintType_ContextStroke:
|
2017-04-29 16:03:20 +03:00
|
|
|
mFallbackType = eStyleSVGFallbackType_NotSet;
|
2019-04-04 14:35:33 +03:00
|
|
|
mFallbackColor = StyleColor::Black();
|
2016-10-11 09:56:11 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
mType = nsStyleSVGPaintType(0);
|
2016-05-03 12:26:27 +03:00
|
|
|
}
|
|
|
|
|
2016-10-11 09:56:11 +03:00
|
|
|
nsStyleSVGPaint& nsStyleSVGPaint::operator=(const nsStyleSVGPaint& aOther) {
|
|
|
|
if (this != &aOther) {
|
|
|
|
Assign(aOther);
|
2007-10-19 19:36:15 +04:00
|
|
|
}
|
2016-10-11 09:56:11 +03:00
|
|
|
return *this;
|
2004-10-15 03:02:53 +04:00
|
|
|
}
|
|
|
|
|
2016-10-11 09:56:11 +03:00
|
|
|
void nsStyleSVGPaint::Assign(const nsStyleSVGPaint& aOther) {
|
|
|
|
MOZ_ASSERT(aOther.mType != nsStyleSVGPaintType(0),
|
|
|
|
"shouldn't copy uninitialized nsStyleSVGPaint");
|
|
|
|
|
|
|
|
switch (aOther.mType) {
|
|
|
|
case eStyleSVGPaintType_None:
|
|
|
|
SetNone();
|
|
|
|
break;
|
|
|
|
case eStyleSVGPaintType_Color:
|
|
|
|
SetColor(aOther.mPaint.mColor);
|
|
|
|
break;
|
|
|
|
case eStyleSVGPaintType_Server:
|
|
|
|
SetPaintServer(aOther.mPaint.mPaintServer, aOther.mFallbackType,
|
|
|
|
aOther.mFallbackColor);
|
|
|
|
break;
|
|
|
|
case eStyleSVGPaintType_ContextFill:
|
|
|
|
case eStyleSVGPaintType_ContextStroke:
|
2017-05-03 00:12:59 +03:00
|
|
|
SetContextValue(aOther.mType, aOther.mFallbackType,
|
|
|
|
aOther.mFallbackColor);
|
2016-10-11 09:56:11 +03:00
|
|
|
break;
|
2016-07-06 08:06:13 +03:00
|
|
|
}
|
2016-10-11 09:56:11 +03:00
|
|
|
}
|
2007-10-19 19:36:15 +04:00
|
|
|
|
2016-10-11 09:56:11 +03:00
|
|
|
void nsStyleSVGPaint::SetNone() {
|
|
|
|
Reset();
|
|
|
|
mType = eStyleSVGPaintType_None;
|
|
|
|
}
|
2007-10-19 19:36:15 +04:00
|
|
|
|
2016-10-11 09:56:11 +03:00
|
|
|
void nsStyleSVGPaint::SetContextValue(nsStyleSVGPaintType aType,
|
2017-05-03 00:12:59 +03:00
|
|
|
nsStyleSVGFallbackType aFallbackType,
|
2019-04-04 14:35:33 +03:00
|
|
|
StyleColor aFallbackColor) {
|
2016-10-11 09:56:11 +03:00
|
|
|
MOZ_ASSERT(aType == eStyleSVGPaintType_ContextFill ||
|
|
|
|
aType == eStyleSVGPaintType_ContextStroke);
|
|
|
|
Reset();
|
|
|
|
mType = aType;
|
2017-05-03 00:12:59 +03:00
|
|
|
mFallbackType = aFallbackType;
|
2016-10-11 09:56:11 +03:00
|
|
|
mFallbackColor = aFallbackColor;
|
|
|
|
}
|
|
|
|
|
2019-04-04 14:35:33 +03:00
|
|
|
void nsStyleSVGPaint::SetColor(StyleColor aColor) {
|
2016-10-11 09:56:11 +03:00
|
|
|
Reset();
|
|
|
|
mType = eStyleSVGPaintType_Color;
|
|
|
|
mPaint.mColor = aColor;
|
|
|
|
}
|
|
|
|
|
Bug 1552708 - Use cbindgen for URIs. r=heycam
This doesn't clean up as much as a whole, but it's a step in the right
direction. In particular, it allows us to start using simple bindings for:
* Filters
* Shapes and images, almost. Need to:
* Get rid of the complex -moz- gradient parsing (let
layout.css.simple-moz-gradient.enabled get to release).
* Counters, almost. Need to:
* Share the Attr representation with Gecko, by not using Option<>.
* Just another variant should be enough (ContentItem::{Attr,Prefixedattr},
maybe).
Which in turn allows us to remove a whole lot of bindings in followups to this.
The setup changes a bit. This also removes the double pointer I complained about
while reviewing the shared UA sheet patches. The old setup is:
```
SpecifiedUrl
* CssUrl
* Arc<CssUrlData>
* String
* UrlExtraData
* UrlValueSource
* Arc<CssUrlData>
* load id
* resolved uri
* CORS mode.
* ...
```
The new one removes the double reference to the url data via URLValue, and looks
like:
```
SpecifiedUrl
* CssUrl
* Arc<CssUrlData>
* String
* UrlExtraData
* CorsMode
* LoadData
* load id
* resolved URI
```
The LoadData is the only mutable bit that C++ can change, and is not used from
Rust. Ideally, in the future, we could just use rust-url to resolve the URL
after parsing or something, and make it all immutable. Maybe.
I've verified that this approach still works with the UA sheet patches (via the
LoadDataSource::Lazy).
The reordering of mWillChange is to avoid nsStyleDisplay from going over the
size limit. We want to split it up anyway in bug 1552587, but mBinding gains a
tag member, which means that we were having a bit of extra padding.
One thing I want to explore is to see if we can abuse rustc's non-zero
optimizations to predict the layout from C++, but that's something to explore at
some other point in time and with a lot of care and help from Michael (who sits
next to me and works on rustc ;)).
Differential Revision: https://phabricator.services.mozilla.com/D31742
2019-05-27 14:45:12 +03:00
|
|
|
void nsStyleSVGPaint::SetPaintServer(const StyleComputedUrl& aPaintServer,
|
2017-05-03 00:12:59 +03:00
|
|
|
nsStyleSVGFallbackType aFallbackType,
|
2019-04-04 14:35:33 +03:00
|
|
|
StyleColor aFallbackColor) {
|
2016-10-11 09:56:11 +03:00
|
|
|
Reset();
|
|
|
|
mType = eStyleSVGPaintType_Server;
|
Bug 1552708 - Use cbindgen for URIs. r=heycam
This doesn't clean up as much as a whole, but it's a step in the right
direction. In particular, it allows us to start using simple bindings for:
* Filters
* Shapes and images, almost. Need to:
* Get rid of the complex -moz- gradient parsing (let
layout.css.simple-moz-gradient.enabled get to release).
* Counters, almost. Need to:
* Share the Attr representation with Gecko, by not using Option<>.
* Just another variant should be enough (ContentItem::{Attr,Prefixedattr},
maybe).
Which in turn allows us to remove a whole lot of bindings in followups to this.
The setup changes a bit. This also removes the double pointer I complained about
while reviewing the shared UA sheet patches. The old setup is:
```
SpecifiedUrl
* CssUrl
* Arc<CssUrlData>
* String
* UrlExtraData
* UrlValueSource
* Arc<CssUrlData>
* load id
* resolved uri
* CORS mode.
* ...
```
The new one removes the double reference to the url data via URLValue, and looks
like:
```
SpecifiedUrl
* CssUrl
* Arc<CssUrlData>
* String
* UrlExtraData
* CorsMode
* LoadData
* load id
* resolved URI
```
The LoadData is the only mutable bit that C++ can change, and is not used from
Rust. Ideally, in the future, we could just use rust-url to resolve the URL
after parsing or something, and make it all immutable. Maybe.
I've verified that this approach still works with the UA sheet patches (via the
LoadDataSource::Lazy).
The reordering of mWillChange is to avoid nsStyleDisplay from going over the
size limit. We want to split it up anyway in bug 1552587, but mBinding gains a
tag member, which means that we were having a bit of extra padding.
One thing I want to explore is to see if we can abuse rustc's non-zero
optimizations to predict the layout from C++, but that's something to explore at
some other point in time and with a lot of care and help from Michael (who sits
next to me and works on rustc ;)).
Differential Revision: https://phabricator.services.mozilla.com/D31742
2019-05-27 14:45:12 +03:00
|
|
|
new (&mPaint.mPaintServer) StyleComputedUrl(aPaintServer);
|
2017-05-03 00:12:59 +03:00
|
|
|
mFallbackType = aFallbackType;
|
2016-10-11 09:56:11 +03:00
|
|
|
mFallbackColor = aFallbackColor;
|
2004-10-15 03:02:53 +04:00
|
|
|
}
|
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
bool nsStyleSVGPaint::operator==(const nsStyleSVGPaint& aOther) const {
|
2016-07-06 08:06:13 +03:00
|
|
|
if (mType != aOther.mType) {
|
2011-10-17 18:59:28 +04:00
|
|
|
return false;
|
2016-07-06 08:06:13 +03:00
|
|
|
}
|
2016-10-11 09:56:11 +03:00
|
|
|
switch (mType) {
|
|
|
|
case eStyleSVGPaintType_Color:
|
|
|
|
return mPaint.mColor == aOther.mPaint.mColor;
|
|
|
|
case eStyleSVGPaintType_Server:
|
Bug 1552708 - Use cbindgen for URIs. r=heycam
This doesn't clean up as much as a whole, but it's a step in the right
direction. In particular, it allows us to start using simple bindings for:
* Filters
* Shapes and images, almost. Need to:
* Get rid of the complex -moz- gradient parsing (let
layout.css.simple-moz-gradient.enabled get to release).
* Counters, almost. Need to:
* Share the Attr representation with Gecko, by not using Option<>.
* Just another variant should be enough (ContentItem::{Attr,Prefixedattr},
maybe).
Which in turn allows us to remove a whole lot of bindings in followups to this.
The setup changes a bit. This also removes the double pointer I complained about
while reviewing the shared UA sheet patches. The old setup is:
```
SpecifiedUrl
* CssUrl
* Arc<CssUrlData>
* String
* UrlExtraData
* UrlValueSource
* Arc<CssUrlData>
* load id
* resolved uri
* CORS mode.
* ...
```
The new one removes the double reference to the url data via URLValue, and looks
like:
```
SpecifiedUrl
* CssUrl
* Arc<CssUrlData>
* String
* UrlExtraData
* CorsMode
* LoadData
* load id
* resolved URI
```
The LoadData is the only mutable bit that C++ can change, and is not used from
Rust. Ideally, in the future, we could just use rust-url to resolve the URL
after parsing or something, and make it all immutable. Maybe.
I've verified that this approach still works with the UA sheet patches (via the
LoadDataSource::Lazy).
The reordering of mWillChange is to avoid nsStyleDisplay from going over the
size limit. We want to split it up anyway in bug 1552587, but mBinding gains a
tag member, which means that we were having a bit of extra padding.
One thing I want to explore is to see if we can abuse rustc's non-zero
optimizations to predict the layout from C++, but that's something to explore at
some other point in time and with a lot of care and help from Michael (who sits
next to me and works on rustc ;)).
Differential Revision: https://phabricator.services.mozilla.com/D31742
2019-05-27 14:45:12 +03:00
|
|
|
return mPaint.mPaintServer == aOther.mPaint.mPaintServer &&
|
2017-05-03 00:12:59 +03:00
|
|
|
mFallbackType == aOther.mFallbackType &&
|
2016-10-11 09:56:11 +03:00
|
|
|
mFallbackColor == aOther.mFallbackColor;
|
|
|
|
case eStyleSVGPaintType_ContextFill:
|
|
|
|
case eStyleSVGPaintType_ContextStroke:
|
2017-05-03 00:12:59 +03:00
|
|
|
return mFallbackType == aOther.mFallbackType &&
|
|
|
|
mFallbackColor == aOther.mFallbackColor;
|
2016-10-11 09:56:11 +03:00
|
|
|
default:
|
|
|
|
MOZ_ASSERT(mType == eStyleSVGPaintType_None, "Unexpected SVG paint type");
|
|
|
|
return true;
|
2016-07-06 08:06:13 +03:00
|
|
|
}
|
2004-10-15 03:02:53 +04:00
|
|
|
}
|
|
|
|
|
2001-06-01 02:19:43 +04:00
|
|
|
// --------------------
|
|
|
|
// nsStylePosition
|
|
|
|
//
|
2019-01-18 20:32:22 +03:00
|
|
|
nsStylePosition::nsStylePosition(const Document& aDocument)
|
2019-02-12 23:45:29 +03:00
|
|
|
: mObjectPosition(Position::FromPercentage(0.5f)),
|
|
|
|
mOffset(StyleRectWithAllSides(LengthPercentageOrAuto::Auto())),
|
2019-02-10 15:55:16 +03:00
|
|
|
mWidth(StyleSize::Auto()),
|
|
|
|
mMinWidth(StyleSize::Auto()),
|
|
|
|
mMaxWidth(StyleMaxSize::None()),
|
|
|
|
mHeight(StyleSize::Auto()),
|
|
|
|
mMinHeight(StyleSize::Auto()),
|
|
|
|
mMaxHeight(StyleMaxSize::None()),
|
|
|
|
mFlexBasis(StyleFlexBasis::Size(StyleSize::Auto())),
|
2016-05-03 12:26:30 +03:00
|
|
|
mGridAutoColumnsMin(eStyleUnit_Auto),
|
|
|
|
mGridAutoColumnsMax(eStyleUnit_Auto),
|
|
|
|
mGridAutoRowsMin(eStyleUnit_Auto),
|
|
|
|
mGridAutoRowsMax(eStyleUnit_Auto),
|
2019-06-27 01:10:04 +03:00
|
|
|
mAspectRatio(0.0f),
|
2016-05-03 12:26:30 +03:00
|
|
|
mGridAutoFlow(NS_STYLE_GRID_AUTO_FLOW_ROW),
|
2016-05-03 12:26:28 +03:00
|
|
|
mBoxSizing(StyleBoxSizing::Content),
|
|
|
|
mAlignContent(NS_STYLE_ALIGN_NORMAL),
|
|
|
|
mAlignItems(NS_STYLE_ALIGN_NORMAL),
|
|
|
|
mAlignSelf(NS_STYLE_ALIGN_AUTO),
|
|
|
|
mJustifyContent(NS_STYLE_JUSTIFY_NORMAL),
|
2018-04-19 18:50:32 +03:00
|
|
|
mSpecifiedJustifyItems(NS_STYLE_JUSTIFY_LEGACY),
|
2017-07-26 16:26:19 +03:00
|
|
|
mJustifyItems(NS_STYLE_JUSTIFY_NORMAL),
|
2016-05-03 12:26:28 +03:00
|
|
|
mJustifySelf(NS_STYLE_JUSTIFY_AUTO),
|
2019-02-19 20:01:59 +03:00
|
|
|
mFlexDirection(StyleFlexDirection::Row),
|
2016-05-03 12:26:28 +03:00
|
|
|
mFlexWrap(NS_STYLE_FLEX_WRAP_NOWRAP),
|
|
|
|
mObjectFit(NS_STYLE_OBJECT_FIT_FILL),
|
|
|
|
mOrder(NS_STYLE_ORDER_INITIAL),
|
|
|
|
mFlexGrow(0.0f),
|
|
|
|
mFlexShrink(1.0f),
|
2019-02-20 02:04:45 +03:00
|
|
|
mZIndex(StyleZIndex::Auto()),
|
2019-06-19 01:29:58 +03:00
|
|
|
mGridTemplateAreas(StyleGridTemplateAreas::None()),
|
2019-04-10 19:00:03 +03:00
|
|
|
mColumnGap(NonNegativeLengthPercentageOrNormal::Normal()),
|
|
|
|
mRowGap(NonNegativeLengthPercentageOrNormal::Normal()) {
|
2009-08-07 18:38:44 +04:00
|
|
|
MOZ_COUNT_CTOR(nsStylePosition);
|
2014-09-10 05:09:32 +04:00
|
|
|
|
2014-03-11 02:54:15 +04:00
|
|
|
// The initial value of grid-auto-columns and grid-auto-rows is 'auto',
|
2015-04-30 21:42:50 +03:00
|
|
|
// which computes to 'minmax(auto, auto)'.
|
2014-03-11 02:54:15 +04:00
|
|
|
|
2014-03-21 19:06:16 +04:00
|
|
|
// Other members get their default constructors
|
|
|
|
// which initialize them to representations of their respective initial value.
|
2014-03-27 19:54:40 +04:00
|
|
|
// mGridTemplate{Rows,Columns}: false and empty arrays for 'none'
|
2014-03-21 19:06:16 +04:00
|
|
|
// mGrid{Column,Row}{Start,End}: false/0/empty values for 'auto'
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
|
|
|
|
2016-05-03 12:26:30 +03:00
|
|
|
nsStylePosition::~nsStylePosition() { MOZ_COUNT_DTOR(nsStylePosition); }
|
2001-06-01 02:19:43 +04:00
|
|
|
|
|
|
|
nsStylePosition::nsStylePosition(const nsStylePosition& aSource)
|
2014-09-10 05:09:32 +04:00
|
|
|
: mObjectPosition(aSource.mObjectPosition),
|
|
|
|
mOffset(aSource.mOffset),
|
2014-06-19 07:17:10 +04:00
|
|
|
mWidth(aSource.mWidth),
|
|
|
|
mMinWidth(aSource.mMinWidth),
|
|
|
|
mMaxWidth(aSource.mMaxWidth),
|
|
|
|
mHeight(aSource.mHeight),
|
|
|
|
mMinHeight(aSource.mMinHeight),
|
|
|
|
mMaxHeight(aSource.mMaxHeight),
|
|
|
|
mFlexBasis(aSource.mFlexBasis),
|
|
|
|
mGridAutoColumnsMin(aSource.mGridAutoColumnsMin),
|
|
|
|
mGridAutoColumnsMax(aSource.mGridAutoColumnsMax),
|
|
|
|
mGridAutoRowsMin(aSource.mGridAutoRowsMin),
|
|
|
|
mGridAutoRowsMax(aSource.mGridAutoRowsMax),
|
2019-06-27 01:10:04 +03:00
|
|
|
mAspectRatio(aSource.mAspectRatio),
|
2014-06-19 07:17:10 +04:00
|
|
|
mGridAutoFlow(aSource.mGridAutoFlow),
|
|
|
|
mBoxSizing(aSource.mBoxSizing),
|
|
|
|
mAlignContent(aSource.mAlignContent),
|
|
|
|
mAlignItems(aSource.mAlignItems),
|
|
|
|
mAlignSelf(aSource.mAlignSelf),
|
2015-11-03 17:18:05 +03:00
|
|
|
mJustifyContent(aSource.mJustifyContent),
|
2017-07-26 16:26:19 +03:00
|
|
|
mSpecifiedJustifyItems(aSource.mSpecifiedJustifyItems),
|
2015-11-03 17:18:05 +03:00
|
|
|
mJustifyItems(aSource.mJustifyItems),
|
2015-11-03 17:18:05 +03:00
|
|
|
mJustifySelf(aSource.mJustifySelf),
|
2014-06-19 07:17:10 +04:00
|
|
|
mFlexDirection(aSource.mFlexDirection),
|
|
|
|
mFlexWrap(aSource.mFlexWrap),
|
2014-09-10 05:09:32 +04:00
|
|
|
mObjectFit(aSource.mObjectFit),
|
2014-06-19 07:17:10 +04:00
|
|
|
mOrder(aSource.mOrder),
|
|
|
|
mFlexGrow(aSource.mFlexGrow),
|
|
|
|
mFlexShrink(aSource.mFlexShrink),
|
|
|
|
mZIndex(aSource.mZIndex),
|
2014-03-11 02:54:14 +04:00
|
|
|
mGridTemplateAreas(aSource.mGridTemplateAreas),
|
2014-03-11 02:54:17 +04:00
|
|
|
mGridColumnStart(aSource.mGridColumnStart),
|
|
|
|
mGridColumnEnd(aSource.mGridColumnEnd),
|
|
|
|
mGridRowStart(aSource.mGridRowStart),
|
|
|
|
mGridRowEnd(aSource.mGridRowEnd),
|
2018-04-24 02:52:51 +03:00
|
|
|
mColumnGap(aSource.mColumnGap),
|
|
|
|
mRowGap(aSource.mRowGap) {
|
2009-08-07 18:38:44 +04:00
|
|
|
MOZ_COUNT_CTOR(nsStylePosition);
|
2017-08-09 04:30:25 +03:00
|
|
|
|
|
|
|
if (aSource.mGridTemplateColumns) {
|
|
|
|
mGridTemplateColumns =
|
|
|
|
MakeUnique<nsStyleGridTemplate>(*aSource.mGridTemplateColumns);
|
|
|
|
}
|
|
|
|
if (aSource.mGridTemplateRows) {
|
|
|
|
mGridTemplateRows =
|
|
|
|
MakeUnique<nsStyleGridTemplate>(*aSource.mGridTemplateRows);
|
|
|
|
}
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
|
|
|
|
2019-01-26 13:00:44 +03:00
|
|
|
static bool IsAutonessEqual(const StyleRect<LengthPercentageOrAuto>& aSides1,
|
|
|
|
const StyleRect<LengthPercentageOrAuto>& aSides2) {
|
2013-09-10 04:08:41 +04:00
|
|
|
NS_FOR_CSS_SIDES(side) {
|
2019-01-26 13:00:44 +03:00
|
|
|
if (aSides1.Get(side).IsAuto() != aSides2.Get(side).IsAuto()) {
|
2013-09-10 04:08:41 +04:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-08-09 04:30:25 +03:00
|
|
|
static bool IsGridTemplateEqual(
|
|
|
|
const UniquePtr<nsStyleGridTemplate>& aOldData,
|
|
|
|
const UniquePtr<nsStyleGridTemplate>& aNewData) {
|
|
|
|
if (aOldData == aNewData) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (!aOldData || !aNewData) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return *aOldData == *aNewData;
|
|
|
|
}
|
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
nsChangeHint nsStylePosition::CalcDifference(
|
|
|
|
const nsStylePosition& aNewData,
|
2019-02-15 02:30:19 +03:00
|
|
|
const nsStyleVisibility& aOldStyleVisibility) const {
|
2014-09-10 05:09:32 +04:00
|
|
|
nsChangeHint hint = nsChangeHint(0);
|
|
|
|
|
2015-01-15 20:51:19 +03:00
|
|
|
// Changes to "z-index" require a repaint.
|
2016-06-21 04:47:54 +03:00
|
|
|
if (mZIndex != aNewData.mZIndex) {
|
2016-05-23 06:26:03 +03:00
|
|
|
hint |= nsChangeHint_RepaintFrame;
|
2015-01-15 09:43:05 +03:00
|
|
|
}
|
|
|
|
|
2015-01-15 20:51:19 +03:00
|
|
|
// Changes to "object-fit" & "object-position" require a repaint. They
|
|
|
|
// may also require a reflow, if we have a nsSubDocumentFrame, so that we
|
|
|
|
// can adjust the size & position of the subdocument.
|
2016-06-21 04:47:54 +03:00
|
|
|
if (mObjectFit != aNewData.mObjectFit ||
|
|
|
|
mObjectPosition != aNewData.mObjectPosition) {
|
2016-05-23 06:26:03 +03:00
|
|
|
hint |= nsChangeHint_RepaintFrame | nsChangeHint_NeedReflow;
|
2015-01-15 20:51:19 +03:00
|
|
|
}
|
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
if (mOrder != aNewData.mOrder) {
|
2014-08-01 22:13:28 +04:00
|
|
|
// "order" impacts both layout order and stacking order, so we need both a
|
|
|
|
// reflow and a repaint when it changes. (Technically, we only need a
|
|
|
|
// reflow if we're in a multi-line flexbox (which we can't be sure about,
|
|
|
|
// since that's determined by styling on our parent) -- there, "order" can
|
|
|
|
// affect which flex line we end up on, & hence can affect our sizing by
|
|
|
|
// changing the group of flex items we're competing with for space.)
|
2016-05-23 06:26:03 +03:00
|
|
|
return hint | nsChangeHint_RepaintFrame | nsChangeHint_AllReflowHints;
|
2014-08-01 22:13:28 +04:00
|
|
|
}
|
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
if (mBoxSizing != aNewData.mBoxSizing) {
|
2009-10-30 06:43:52 +03:00
|
|
|
// Can affect both widths and heights; just a bad scene.
|
2016-05-23 06:26:03 +03:00
|
|
|
return hint | nsChangeHint_AllReflowHints;
|
2009-10-30 04:47:43 +03:00
|
|
|
}
|
|
|
|
|
2012-07-07 04:06:19 +04:00
|
|
|
// Properties that apply to flex items:
|
2014-08-01 22:13:28 +04:00
|
|
|
// XXXdholbert These should probably be more targeted (bug 819536)
|
2016-06-21 04:47:54 +03:00
|
|
|
if (mAlignSelf != aNewData.mAlignSelf || mFlexBasis != aNewData.mFlexBasis ||
|
|
|
|
mFlexGrow != aNewData.mFlexGrow || mFlexShrink != aNewData.mFlexShrink) {
|
2016-05-23 06:26:03 +03:00
|
|
|
return hint | nsChangeHint_AllReflowHints;
|
2012-07-07 04:06:19 +04:00
|
|
|
}
|
|
|
|
|
2013-12-05 22:57:50 +04:00
|
|
|
// Properties that apply to flex containers:
|
|
|
|
// - flex-direction can swap a flex container between vertical & horizontal.
|
|
|
|
// - align-items can change the sizing of a flex container & the positioning
|
|
|
|
// of its children.
|
|
|
|
// - flex-wrap changes whether a flex container's children are wrapped, which
|
|
|
|
// impacts their sizing/positioning and hence impacts the container's size.
|
2016-06-21 04:47:54 +03:00
|
|
|
if (mAlignItems != aNewData.mAlignItems ||
|
|
|
|
mFlexDirection != aNewData.mFlexDirection ||
|
|
|
|
mFlexWrap != aNewData.mFlexWrap) {
|
2016-05-23 06:26:03 +03:00
|
|
|
return hint | nsChangeHint_AllReflowHints;
|
2012-07-07 04:06:20 +04:00
|
|
|
}
|
|
|
|
|
2014-03-11 02:54:13 +04:00
|
|
|
// Properties that apply to grid containers:
|
2014-03-11 02:54:17 +04:00
|
|
|
// FIXME: only for grid containers
|
|
|
|
// (ie. 'display: grid' or 'display: inline-grid')
|
2017-08-09 04:30:25 +03:00
|
|
|
if (!IsGridTemplateEqual(mGridTemplateColumns,
|
|
|
|
aNewData.mGridTemplateColumns) ||
|
|
|
|
!IsGridTemplateEqual(mGridTemplateRows, aNewData.mGridTemplateRows) ||
|
2016-06-21 04:47:54 +03:00
|
|
|
mGridTemplateAreas != aNewData.mGridTemplateAreas ||
|
|
|
|
mGridAutoColumnsMin != aNewData.mGridAutoColumnsMin ||
|
|
|
|
mGridAutoColumnsMax != aNewData.mGridAutoColumnsMax ||
|
|
|
|
mGridAutoRowsMin != aNewData.mGridAutoRowsMin ||
|
|
|
|
mGridAutoRowsMax != aNewData.mGridAutoRowsMax ||
|
|
|
|
mGridAutoFlow != aNewData.mGridAutoFlow) {
|
2016-05-23 06:26:03 +03:00
|
|
|
return hint | nsChangeHint_AllReflowHints;
|
2014-03-11 02:54:13 +04:00
|
|
|
}
|
|
|
|
|
2014-03-11 02:54:17 +04:00
|
|
|
// Properties that apply to grid items:
|
|
|
|
// FIXME: only for grid items
|
|
|
|
// (ie. parent frame is 'display: grid' or 'display: inline-grid')
|
2016-06-21 04:47:54 +03:00
|
|
|
if (mGridColumnStart != aNewData.mGridColumnStart ||
|
|
|
|
mGridColumnEnd != aNewData.mGridColumnEnd ||
|
|
|
|
mGridRowStart != aNewData.mGridRowStart ||
|
|
|
|
mGridRowEnd != aNewData.mGridRowEnd ||
|
2018-04-24 02:52:51 +03:00
|
|
|
mColumnGap != aNewData.mColumnGap || mRowGap != aNewData.mRowGap) {
|
2016-05-23 06:26:03 +03:00
|
|
|
return hint | nsChangeHint_AllReflowHints;
|
2014-03-11 02:54:17 +04:00
|
|
|
}
|
2014-03-11 02:54:13 +04:00
|
|
|
|
2015-11-03 17:18:05 +03:00
|
|
|
// Changing 'justify-content/items/self' might affect the positioning,
|
2015-11-03 17:18:05 +03:00
|
|
|
// but it won't affect any sizing.
|
2016-06-21 04:47:54 +03:00
|
|
|
if (mJustifyContent != aNewData.mJustifyContent ||
|
|
|
|
mJustifyItems != aNewData.mJustifyItems ||
|
|
|
|
mJustifySelf != aNewData.mJustifySelf) {
|
2016-05-23 06:26:03 +03:00
|
|
|
hint |= nsChangeHint_NeedReflow;
|
2012-07-07 04:06:19 +04:00
|
|
|
}
|
|
|
|
|
2017-07-26 16:26:19 +03:00
|
|
|
// No need to do anything if mSpecifiedJustifyItems changes, as long as
|
|
|
|
// mJustifyItems (tested above) is unchanged.
|
|
|
|
if (mSpecifiedJustifyItems != aNewData.mSpecifiedJustifyItems) {
|
|
|
|
hint |= nsChangeHint_NeutralChange;
|
|
|
|
}
|
|
|
|
|
2015-09-10 22:07:26 +03:00
|
|
|
// 'align-content' doesn't apply to a single-line flexbox but we don't know
|
|
|
|
// if we're a flex container at this point so we can't optimize for that.
|
2016-06-21 04:47:54 +03:00
|
|
|
if (mAlignContent != aNewData.mAlignContent) {
|
2016-05-23 06:26:03 +03:00
|
|
|
hint |= nsChangeHint_NeedReflow;
|
2013-12-05 22:57:50 +04:00
|
|
|
}
|
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
bool widthChanged = mWidth != aNewData.mWidth ||
|
|
|
|
mMinWidth != aNewData.mMinWidth ||
|
|
|
|
mMaxWidth != aNewData.mMaxWidth;
|
|
|
|
bool heightChanged = mHeight != aNewData.mHeight ||
|
|
|
|
mMinHeight != aNewData.mMinHeight ||
|
|
|
|
mMaxHeight != aNewData.mMaxHeight;
|
2015-10-23 02:57:35 +03:00
|
|
|
|
2019-06-11 12:12:10 +03:00
|
|
|
// It doesn't matter whether we're looking at the old or new visibility
|
|
|
|
// struct, since a change between vertical and horizontal writing-mode will
|
|
|
|
// cause a reframe.
|
2019-02-15 02:30:19 +03:00
|
|
|
bool isVertical = WritingMode(&aOldStyleVisibility).IsVertical();
|
|
|
|
if (isVertical ? widthChanged : heightChanged) {
|
|
|
|
hint |= nsChangeHint_ReflowHintsForBSizeChange;
|
|
|
|
}
|
2015-10-23 02:57:35 +03:00
|
|
|
|
2019-02-15 02:30:19 +03:00
|
|
|
if (isVertical ? heightChanged : widthChanged) {
|
|
|
|
hint |= nsChangeHint_ReflowHintsForISizeChange;
|
2009-08-04 05:22:13 +04:00
|
|
|
}
|
|
|
|
|
2019-06-27 01:10:04 +03:00
|
|
|
if (mAspectRatio != aNewData.mAspectRatio) {
|
|
|
|
hint |= nsChangeHint_ReflowHintsForISizeChange |
|
|
|
|
nsChangeHint_ReflowHintsForBSizeChange;
|
|
|
|
}
|
|
|
|
|
2015-08-04 07:41:50 +03:00
|
|
|
// If any of the offsets have changed, then return the respective hints
|
|
|
|
// so that we would hopefully be able to avoid reflowing.
|
Bug 157681 - Part 2: Optimize positioned frame offset changes by moving the frame as opposed to reflowing it in case we know that the size of the frame will not change; r=dbaron
This patch adds a change hint to signal that one of the offsets on a
frame has been changed. When processing the hint, we do one of the
following things based on the position property of the frame.
* For static frames, we ignore the offset changes completely, as they
will not change the layout.
* For relative positioned frames, this patch refactors the
nsHTMLReflowState::ComputeRelativeOffsets function so that it can be
used from other callers, and it uses that to compute the new relative
offsets, and uses the offsets computed previously to compute the new
position of the frame.
* For absolute positioned frames, we set up a fake parent reflow state
object, and then we create a new reflow state object for the frame in
question. This setup is similar to what nsFrame::BoxReflow does.
Once we have the new reflow state object, we use it to compute the
absolute offsets, and then we use the computed offsets to set the new
position of the frame. The offset computation is similar to what
nsAbsoluteContainingBlock::ReflowAbsoluteFrame does. In some cases
where it is possible for the dimensions of the frame to change based
on the offset changes, we fall back to a full reflow.
2012-06-06 08:53:48 +04:00
|
|
|
// Note that it is possible that we'll need to reflow when processing
|
|
|
|
// restyles, but we don't have enough information to make a good decision
|
|
|
|
// right now.
|
2013-09-10 04:08:41 +04:00
|
|
|
// Don't try to handle changes between "auto" and non-auto efficiently;
|
|
|
|
// that's tricky to do and will hardly ever be able to avoid a reflow.
|
2016-06-21 04:47:54 +03:00
|
|
|
if (mOffset != aNewData.mOffset) {
|
|
|
|
if (IsAutonessEqual(mOffset, aNewData.mOffset)) {
|
2016-05-23 06:26:03 +03:00
|
|
|
hint |=
|
|
|
|
nsChangeHint_RecomputePosition | nsChangeHint_UpdateParentOverflow;
|
2013-09-10 04:08:41 +04:00
|
|
|
} else {
|
2019-06-15 02:29:34 +03:00
|
|
|
hint |= nsChangeHint_NeedReflow | nsChangeHint_ReflowChangesSizeOrPosition;
|
2013-09-10 04:08:41 +04:00
|
|
|
}
|
Bug 157681 - Part 2: Optimize positioned frame offset changes by moving the frame as opposed to reflowing it in case we know that the size of the frame will not change; r=dbaron
This patch adds a change hint to signal that one of the offsets on a
frame has been changed. When processing the hint, we do one of the
following things based on the position property of the frame.
* For static frames, we ignore the offset changes completely, as they
will not change the layout.
* For relative positioned frames, this patch refactors the
nsHTMLReflowState::ComputeRelativeOffsets function so that it can be
used from other callers, and it uses that to compute the new relative
offsets, and uses the offsets computed previously to compute the new
position of the frame.
* For absolute positioned frames, we set up a fake parent reflow state
object, and then we create a new reflow state object for the frame in
question. This setup is similar to what nsFrame::BoxReflow does.
Once we have the new reflow state object, we use it to compute the
absolute offsets, and then we use the computed offsets to set the new
position of the frame. The offset computation is similar to what
nsAbsoluteContainingBlock::ReflowAbsoluteFrame does. In some cases
where it is possible for the dimensions of the frame to change based
on the offset changes, we fall back to a full reflow.
2012-06-06 08:53:48 +04:00
|
|
|
}
|
|
|
|
return hint;
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
|
|
|
|
2018-03-22 21:20:41 +03:00
|
|
|
uint8_t nsStylePosition::UsedAlignSelf(ComputedStyle* aParent) const {
|
2015-11-03 17:18:06 +03:00
|
|
|
if (mAlignSelf != NS_STYLE_ALIGN_AUTO) {
|
2015-11-28 23:37:44 +03:00
|
|
|
return mAlignSelf;
|
2015-11-03 17:18:06 +03:00
|
|
|
}
|
|
|
|
if (MOZ_LIKELY(aParent)) {
|
2016-10-03 23:05:35 +03:00
|
|
|
auto parentAlignItems = aParent->StylePosition()->mAlignItems;
|
2015-11-03 17:18:06 +03:00
|
|
|
MOZ_ASSERT(!(parentAlignItems & NS_STYLE_ALIGN_LEGACY),
|
|
|
|
"align-items can't have 'legacy'");
|
2015-11-28 23:37:44 +03:00
|
|
|
return parentAlignItems;
|
2015-11-03 17:18:06 +03:00
|
|
|
}
|
2016-01-05 23:27:13 +03:00
|
|
|
return NS_STYLE_ALIGN_NORMAL;
|
2015-11-03 17:18:05 +03:00
|
|
|
}
|
|
|
|
|
2018-03-22 21:20:41 +03:00
|
|
|
uint8_t nsStylePosition::UsedJustifySelf(ComputedStyle* aParent) const {
|
2015-11-03 17:18:05 +03:00
|
|
|
if (mJustifySelf != NS_STYLE_JUSTIFY_AUTO) {
|
2015-11-28 23:37:44 +03:00
|
|
|
return mJustifySelf;
|
2015-11-03 17:18:05 +03:00
|
|
|
}
|
|
|
|
if (MOZ_LIKELY(aParent)) {
|
2017-07-26 16:26:19 +03:00
|
|
|
auto inheritedJustifyItems = aParent->StylePosition()->mJustifyItems;
|
2015-11-28 23:37:44 +03:00
|
|
|
return inheritedJustifyItems & ~NS_STYLE_JUSTIFY_LEGACY;
|
2015-11-03 17:18:05 +03:00
|
|
|
}
|
2016-01-05 23:27:13 +03:00
|
|
|
return NS_STYLE_JUSTIFY_NORMAL;
|
2015-11-03 17:18:05 +03:00
|
|
|
}
|
|
|
|
|
2017-08-09 04:30:25 +03:00
|
|
|
static StaticAutoPtr<nsStyleGridTemplate> sDefaultGridTemplate;
|
|
|
|
|
|
|
|
static const nsStyleGridTemplate& DefaultGridTemplate() {
|
|
|
|
if (!sDefaultGridTemplate) {
|
|
|
|
sDefaultGridTemplate = new nsStyleGridTemplate;
|
|
|
|
ClearOnShutdown(&sDefaultGridTemplate);
|
|
|
|
}
|
|
|
|
return *sDefaultGridTemplate;
|
|
|
|
}
|
|
|
|
|
|
|
|
const nsStyleGridTemplate& nsStylePosition::GridTemplateColumns() const {
|
|
|
|
return mGridTemplateColumns ? *mGridTemplateColumns : DefaultGridTemplate();
|
|
|
|
}
|
|
|
|
|
|
|
|
const nsStyleGridTemplate& nsStylePosition::GridTemplateRows() const {
|
|
|
|
return mGridTemplateRows ? *mGridTemplateRows : DefaultGridTemplate();
|
|
|
|
}
|
|
|
|
|
2001-06-01 02:19:43 +04:00
|
|
|
// --------------------
|
|
|
|
// nsStyleTable
|
|
|
|
//
|
|
|
|
|
2019-01-18 20:32:22 +03:00
|
|
|
nsStyleTable::nsStyleTable(const Document& aDocument)
|
2016-05-03 12:26:28 +03:00
|
|
|
: mLayoutStrategy(NS_STYLE_TABLE_LAYOUT_AUTO), mSpan(1) {
|
2009-08-07 18:38:44 +04:00
|
|
|
MOZ_COUNT_CTOR(nsStyleTable);
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
|
|
|
|
2009-08-07 18:38:44 +04:00
|
|
|
nsStyleTable::~nsStyleTable() { MOZ_COUNT_DTOR(nsStyleTable); }
|
2001-06-01 02:19:43 +04:00
|
|
|
|
|
|
|
nsStyleTable::nsStyleTable(const nsStyleTable& aSource)
|
2014-06-19 07:17:10 +04:00
|
|
|
: mLayoutStrategy(aSource.mLayoutStrategy), mSpan(aSource.mSpan) {
|
2009-08-07 18:38:44 +04:00
|
|
|
MOZ_COUNT_CTOR(nsStyleTable);
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
nsChangeHint nsStyleTable::CalcDifference(const nsStyleTable& aNewData) const {
|
2016-07-06 08:06:13 +03:00
|
|
|
if (mSpan != aNewData.mSpan || mLayoutStrategy != aNewData.mLayoutStrategy) {
|
2016-07-06 08:06:14 +03:00
|
|
|
return nsChangeHint_ReconstructFrame;
|
2016-07-06 08:06:13 +03:00
|
|
|
}
|
2016-07-17 17:20:21 +03:00
|
|
|
return nsChangeHint(0);
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------
|
|
|
|
// nsStyleTableBorder
|
|
|
|
|
2019-01-18 20:32:22 +03:00
|
|
|
nsStyleTableBorder::nsStyleTableBorder(const Document& aDocument)
|
2016-05-03 12:26:29 +03:00
|
|
|
: mBorderSpacingCol(0),
|
|
|
|
mBorderSpacingRow(0),
|
2019-05-06 02:39:27 +03:00
|
|
|
mBorderCollapse(StyleBorderCollapse::Separate),
|
2016-05-03 12:26:29 +03:00
|
|
|
mCaptionSide(NS_STYLE_CAPTION_SIDE_TOP),
|
|
|
|
mEmptyCells(NS_STYLE_TABLE_EMPTY_CELLS_SHOW) {
|
2009-08-07 18:38:44 +04:00
|
|
|
MOZ_COUNT_CTOR(nsStyleTableBorder);
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
|
|
|
|
2016-05-03 12:26:30 +03:00
|
|
|
nsStyleTableBorder::~nsStyleTableBorder() {
|
2009-08-07 18:38:44 +04:00
|
|
|
MOZ_COUNT_DTOR(nsStyleTableBorder);
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
nsStyleTableBorder::nsStyleTableBorder(const nsStyleTableBorder& aSource)
|
2015-03-20 07:16:00 +03:00
|
|
|
: mBorderSpacingCol(aSource.mBorderSpacingCol),
|
|
|
|
mBorderSpacingRow(aSource.mBorderSpacingRow),
|
2014-06-19 07:17:10 +04:00
|
|
|
mBorderCollapse(aSource.mBorderCollapse),
|
|
|
|
mCaptionSide(aSource.mCaptionSide),
|
|
|
|
mEmptyCells(aSource.mEmptyCells) {
|
2009-08-07 18:38:44 +04:00
|
|
|
MOZ_COUNT_CTOR(nsStyleTableBorder);
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
nsChangeHint nsStyleTableBorder::CalcDifference(
|
|
|
|
const nsStyleTableBorder& aNewData) const {
|
2003-02-13 22:06:18 +03:00
|
|
|
// Border-collapse changes need a reframe, because we use a different frame
|
|
|
|
// class for table cells in the collapsed border model. This is used to
|
|
|
|
// conserve memory when using the separated border model (collapsed borders
|
|
|
|
// require extra state to be stored).
|
2016-06-21 04:47:54 +03:00
|
|
|
if (mBorderCollapse != aNewData.mBorderCollapse) {
|
2016-07-06 08:06:14 +03:00
|
|
|
return nsChangeHint_ReconstructFrame;
|
2003-02-13 22:06:18 +03:00
|
|
|
}
|
2016-05-03 12:26:29 +03:00
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
if ((mCaptionSide == aNewData.mCaptionSide) &&
|
|
|
|
(mBorderSpacingCol == aNewData.mBorderSpacingCol) &&
|
|
|
|
(mBorderSpacingRow == aNewData.mBorderSpacingRow)) {
|
2016-07-06 08:06:13 +03:00
|
|
|
if (mEmptyCells == aNewData.mEmptyCells) {
|
2016-07-17 17:20:21 +03:00
|
|
|
return nsChangeHint(0);
|
2016-07-06 08:06:13 +03:00
|
|
|
}
|
2001-06-01 02:19:43 +04:00
|
|
|
return NS_STYLE_HINT_VISUAL;
|
2016-07-06 08:06:13 +03:00
|
|
|
} else {
|
2016-07-06 06:40:49 +03:00
|
|
|
return NS_STYLE_HINT_REFLOW;
|
2016-07-06 08:06:13 +03:00
|
|
|
}
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
|
|
|
|
2019-06-07 17:13:17 +03:00
|
|
|
template <>
|
|
|
|
bool StyleGradient::IsOpaque() const {
|
|
|
|
for (auto& stop : items.AsSpan()) {
|
2019-04-30 23:37:54 +03:00
|
|
|
if (stop.IsInterpolationHint()) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto& color = stop.IsSimpleColorStop() ? stop.AsSimpleColorStop()
|
|
|
|
: stop.AsComplexColorStop().color;
|
|
|
|
if (color.MaybeTransparent()) {
|
2018-06-07 08:55:26 +03:00
|
|
|
// We don't know the foreground color here, so if it's being used
|
|
|
|
// we must assume it might be transparent.
|
2011-10-17 18:59:28 +04:00
|
|
|
return false;
|
2016-07-06 08:06:13 +03:00
|
|
|
}
|
2011-01-03 04:48:09 +03:00
|
|
|
}
|
|
|
|
|
2019-04-30 23:37:54 +03:00
|
|
|
return true;
|
2012-08-27 08:09:46 +04:00
|
|
|
}
|
|
|
|
|
2016-11-02 11:58:31 +03:00
|
|
|
// --------------------
|
|
|
|
// nsStyleImageRequest
|
|
|
|
|
|
|
|
/**
|
2018-10-04 03:20:50 +03:00
|
|
|
* Runnable to release the nsStyleImageRequest's mRequestProxy
|
|
|
|
* and mImageTracker on the main thread, and to perform
|
2016-11-02 11:58:31 +03:00
|
|
|
* any necessary unlocking and untracking of the image.
|
|
|
|
*/
|
|
|
|
class StyleImageRequestCleanupTask : public mozilla::Runnable {
|
|
|
|
public:
|
|
|
|
typedef nsStyleImageRequest::Mode Mode;
|
|
|
|
|
|
|
|
StyleImageRequestCleanupTask(Mode aModeFlags,
|
|
|
|
already_AddRefed<imgRequestProxy> aRequestProxy,
|
|
|
|
already_AddRefed<ImageTracker> aImageTracker)
|
2017-06-12 22:34:10 +03:00
|
|
|
: mozilla::Runnable("StyleImageRequestCleanupTask"),
|
|
|
|
mModeFlags(aModeFlags),
|
2016-11-02 11:58:31 +03:00
|
|
|
mRequestProxy(aRequestProxy),
|
|
|
|
mImageTracker(aImageTracker) {}
|
|
|
|
|
2018-02-06 09:46:57 +03:00
|
|
|
NS_IMETHOD Run() final {
|
2017-03-14 16:29:55 +03:00
|
|
|
MOZ_ASSERT(!mRequestProxy || NS_IsMainThread(),
|
|
|
|
"If mRequestProxy is non-null, we need to run on main thread!");
|
2016-11-02 11:58:31 +03:00
|
|
|
|
|
|
|
if (!mRequestProxy) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2016-11-02 11:58:32 +03:00
|
|
|
if (mModeFlags & Mode::Track) {
|
|
|
|
MOZ_ASSERT(mImageTracker);
|
|
|
|
mImageTracker->Remove(mRequestProxy);
|
|
|
|
} else {
|
2016-11-02 11:58:31 +03:00
|
|
|
mRequestProxy->UnlockImage();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mModeFlags & Mode::Discard) {
|
|
|
|
mRequestProxy->RequestDiscard();
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
2017-03-14 16:29:55 +03:00
|
|
|
virtual ~StyleImageRequestCleanupTask() {
|
|
|
|
MOZ_ASSERT((!mRequestProxy && !mImageTracker) || NS_IsMainThread(),
|
|
|
|
"mRequestProxy and mImageTracker's destructor need to run "
|
|
|
|
"on the main thread!");
|
|
|
|
}
|
2016-11-02 11:58:31 +03:00
|
|
|
|
|
|
|
private:
|
|
|
|
Mode mModeFlags;
|
|
|
|
// Since we always dispatch this runnable to the main thread, these will be
|
|
|
|
// released on the main thread when the runnable itself is released.
|
|
|
|
RefPtr<imgRequestProxy> mRequestProxy;
|
|
|
|
RefPtr<ImageTracker> mImageTracker;
|
|
|
|
};
|
|
|
|
|
|
|
|
nsStyleImageRequest::nsStyleImageRequest(Mode aModeFlags,
|
Bug 1552708 - Use cbindgen for URIs. r=heycam
This doesn't clean up as much as a whole, but it's a step in the right
direction. In particular, it allows us to start using simple bindings for:
* Filters
* Shapes and images, almost. Need to:
* Get rid of the complex -moz- gradient parsing (let
layout.css.simple-moz-gradient.enabled get to release).
* Counters, almost. Need to:
* Share the Attr representation with Gecko, by not using Option<>.
* Just another variant should be enough (ContentItem::{Attr,Prefixedattr},
maybe).
Which in turn allows us to remove a whole lot of bindings in followups to this.
The setup changes a bit. This also removes the double pointer I complained about
while reviewing the shared UA sheet patches. The old setup is:
```
SpecifiedUrl
* CssUrl
* Arc<CssUrlData>
* String
* UrlExtraData
* UrlValueSource
* Arc<CssUrlData>
* load id
* resolved uri
* CORS mode.
* ...
```
The new one removes the double reference to the url data via URLValue, and looks
like:
```
SpecifiedUrl
* CssUrl
* Arc<CssUrlData>
* String
* UrlExtraData
* CorsMode
* LoadData
* load id
* resolved URI
```
The LoadData is the only mutable bit that C++ can change, and is not used from
Rust. Ideally, in the future, we could just use rust-url to resolve the URL
after parsing or something, and make it all immutable. Maybe.
I've verified that this approach still works with the UA sheet patches (via the
LoadDataSource::Lazy).
The reordering of mWillChange is to avoid nsStyleDisplay from going over the
size limit. We want to split it up anyway in bug 1552587, but mBinding gains a
tag member, which means that we were having a bit of extra padding.
One thing I want to explore is to see if we can abuse rustc's non-zero
optimizations to predict the layout from C++, but that's something to explore at
some other point in time and with a lot of care and help from Michael (who sits
next to me and works on rustc ;)).
Differential Revision: https://phabricator.services.mozilla.com/D31742
2019-05-27 14:45:12 +03:00
|
|
|
const StyleComputedImageUrl& aImageURL)
|
|
|
|
: mImageURL(aImageURL), mModeFlags(aModeFlags), mResolved(false) {}
|
2017-05-02 11:20:01 +03:00
|
|
|
|
2016-11-02 11:58:31 +03:00
|
|
|
nsStyleImageRequest::~nsStyleImageRequest() {
|
|
|
|
// We may or may not be being destroyed on the main thread. To clean
|
|
|
|
// up, we must untrack and unlock the image (depending on mModeFlags),
|
2018-10-04 03:20:50 +03:00
|
|
|
// and release mRequestProxy and mImageTracker, all on the main thread.
|
2016-11-02 11:58:31 +03:00
|
|
|
{
|
|
|
|
RefPtr<StyleImageRequestCleanupTask> task =
|
|
|
|
new StyleImageRequestCleanupTask(mModeFlags, mRequestProxy.forget(),
|
|
|
|
mImageTracker.forget());
|
2017-05-08 10:08:46 +03:00
|
|
|
if (NS_IsMainThread()) {
|
2016-11-02 11:58:31 +03:00
|
|
|
task->Run();
|
|
|
|
} else {
|
2017-05-08 10:08:46 +03:00
|
|
|
if (mDocGroup) {
|
2017-07-26 11:13:35 +03:00
|
|
|
mDocGroup->Dispatch(TaskCategory::Other, task.forget());
|
2017-05-08 10:08:46 +03:00
|
|
|
} else {
|
|
|
|
// if Resolve was not called at some point, mDocGroup is not set.
|
2017-08-23 03:52:22 +03:00
|
|
|
SystemGroup::Dispatch(TaskCategory::Other, task.forget());
|
2017-05-08 10:08:46 +03:00
|
|
|
}
|
2016-11-02 11:58:31 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
MOZ_ASSERT(!mRequestProxy);
|
|
|
|
MOZ_ASSERT(!mImageTracker);
|
|
|
|
}
|
|
|
|
|
2019-02-02 21:42:25 +03:00
|
|
|
bool nsStyleImageRequest::Resolve(Document& aDocument,
|
2018-02-22 22:03:43 +03:00
|
|
|
const nsStyleImageRequest* aOldImageRequest) {
|
2016-11-02 11:58:31 +03:00
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
MOZ_ASSERT(!IsResolved(), "already resolved");
|
|
|
|
|
|
|
|
mResolved = true;
|
2017-04-11 17:56:41 +03:00
|
|
|
|
2019-02-02 21:42:25 +03:00
|
|
|
nsIURI* docURI = aDocument.GetDocumentURI();
|
Bug 1552708 - Use cbindgen for URIs. r=heycam
This doesn't clean up as much as a whole, but it's a step in the right
direction. In particular, it allows us to start using simple bindings for:
* Filters
* Shapes and images, almost. Need to:
* Get rid of the complex -moz- gradient parsing (let
layout.css.simple-moz-gradient.enabled get to release).
* Counters, almost. Need to:
* Share the Attr representation with Gecko, by not using Option<>.
* Just another variant should be enough (ContentItem::{Attr,Prefixedattr},
maybe).
Which in turn allows us to remove a whole lot of bindings in followups to this.
The setup changes a bit. This also removes the double pointer I complained about
while reviewing the shared UA sheet patches. The old setup is:
```
SpecifiedUrl
* CssUrl
* Arc<CssUrlData>
* String
* UrlExtraData
* UrlValueSource
* Arc<CssUrlData>
* load id
* resolved uri
* CORS mode.
* ...
```
The new one removes the double reference to the url data via URLValue, and looks
like:
```
SpecifiedUrl
* CssUrl
* Arc<CssUrlData>
* String
* UrlExtraData
* CorsMode
* LoadData
* load id
* resolved URI
```
The LoadData is the only mutable bit that C++ can change, and is not used from
Rust. Ideally, in the future, we could just use rust-url to resolve the URL
after parsing or something, and make it all immutable. Maybe.
I've verified that this approach still works with the UA sheet patches (via the
LoadDataSource::Lazy).
The reordering of mWillChange is to avoid nsStyleDisplay from going over the
size limit. We want to split it up anyway in bug 1552587, but mBinding gains a
tag member, which means that we were having a bit of extra padding.
One thing I want to explore is to see if we can abuse rustc's non-zero
optimizations to predict the layout from C++, but that's something to explore at
some other point in time and with a lot of care and help from Michael (who sits
next to me and works on rustc ;)).
Differential Revision: https://phabricator.services.mozilla.com/D31742
2019-05-27 14:45:12 +03:00
|
|
|
if (GetImageValue().HasRef()) {
|
2017-04-11 17:56:41 +03:00
|
|
|
bool isEqualExceptRef = false;
|
|
|
|
RefPtr<nsIURI> imageURI = GetImageURI();
|
2018-04-14 18:24:45 +03:00
|
|
|
if (!imageURI) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (NS_SUCCEEDED(imageURI->EqualsExceptRef(docURI, &isEqualExceptRef)) &&
|
|
|
|
isEqualExceptRef) {
|
2017-04-11 17:56:41 +03:00
|
|
|
// Prevent loading an internal resource.
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-22 22:03:43 +03:00
|
|
|
// TODO(emilio, bug 1440442): This is a hackaround to avoid flickering due the
|
|
|
|
// lack of non-http image caching in imagelib (bug 1406134), which causes
|
|
|
|
// stuff like bug 1439285. Cleanest fix if that doesn't get fixed is bug
|
|
|
|
// 1440305, but that seems too risky, and a lot of work to do before 60.
|
|
|
|
//
|
2019-02-04 19:03:25 +03:00
|
|
|
// Once that's fixed, the "old style" argument to TriggerImageLoads can go
|
|
|
|
// away.
|
2019-02-02 21:42:25 +03:00
|
|
|
if (nsContentUtils::IsChromeDoc(&aDocument) && aOldImageRequest &&
|
2018-02-22 22:03:43 +03:00
|
|
|
aOldImageRequest->IsResolved() && DefinitelyEquals(*aOldImageRequest)) {
|
2019-02-02 21:42:25 +03:00
|
|
|
MOZ_ASSERT(aOldImageRequest->mDocGroup == aDocument.GetDocGroup());
|
2018-02-22 22:03:43 +03:00
|
|
|
MOZ_ASSERT(mModeFlags == aOldImageRequest->mModeFlags);
|
|
|
|
|
|
|
|
mDocGroup = aOldImageRequest->mDocGroup;
|
Bug 1552708 - Use cbindgen for URIs. r=heycam
This doesn't clean up as much as a whole, but it's a step in the right
direction. In particular, it allows us to start using simple bindings for:
* Filters
* Shapes and images, almost. Need to:
* Get rid of the complex -moz- gradient parsing (let
layout.css.simple-moz-gradient.enabled get to release).
* Counters, almost. Need to:
* Share the Attr representation with Gecko, by not using Option<>.
* Just another variant should be enough (ContentItem::{Attr,Prefixedattr},
maybe).
Which in turn allows us to remove a whole lot of bindings in followups to this.
The setup changes a bit. This also removes the double pointer I complained about
while reviewing the shared UA sheet patches. The old setup is:
```
SpecifiedUrl
* CssUrl
* Arc<CssUrlData>
* String
* UrlExtraData
* UrlValueSource
* Arc<CssUrlData>
* load id
* resolved uri
* CORS mode.
* ...
```
The new one removes the double reference to the url data via URLValue, and looks
like:
```
SpecifiedUrl
* CssUrl
* Arc<CssUrlData>
* String
* UrlExtraData
* CorsMode
* LoadData
* load id
* resolved URI
```
The LoadData is the only mutable bit that C++ can change, and is not used from
Rust. Ideally, in the future, we could just use rust-url to resolve the URL
after parsing or something, and make it all immutable. Maybe.
I've verified that this approach still works with the UA sheet patches (via the
LoadDataSource::Lazy).
The reordering of mWillChange is to avoid nsStyleDisplay from going over the
size limit. We want to split it up anyway in bug 1552587, but mBinding gains a
tag member, which means that we were having a bit of extra padding.
One thing I want to explore is to see if we can abuse rustc's non-zero
optimizations to predict the layout from C++, but that's something to explore at
some other point in time and with a lot of care and help from Michael (who sits
next to me and works on rustc ;)).
Differential Revision: https://phabricator.services.mozilla.com/D31742
2019-05-27 14:45:12 +03:00
|
|
|
mImageURL = aOldImageRequest->mImageURL;
|
|
|
|
|
2018-02-22 22:03:43 +03:00
|
|
|
mRequestProxy = aOldImageRequest->mRequestProxy;
|
|
|
|
} else {
|
2019-02-02 21:42:25 +03:00
|
|
|
mDocGroup = aDocument.GetDocGroup();
|
Bug 1552708 - Use cbindgen for URIs. r=heycam
This doesn't clean up as much as a whole, but it's a step in the right
direction. In particular, it allows us to start using simple bindings for:
* Filters
* Shapes and images, almost. Need to:
* Get rid of the complex -moz- gradient parsing (let
layout.css.simple-moz-gradient.enabled get to release).
* Counters, almost. Need to:
* Share the Attr representation with Gecko, by not using Option<>.
* Just another variant should be enough (ContentItem::{Attr,Prefixedattr},
maybe).
Which in turn allows us to remove a whole lot of bindings in followups to this.
The setup changes a bit. This also removes the double pointer I complained about
while reviewing the shared UA sheet patches. The old setup is:
```
SpecifiedUrl
* CssUrl
* Arc<CssUrlData>
* String
* UrlExtraData
* UrlValueSource
* Arc<CssUrlData>
* load id
* resolved uri
* CORS mode.
* ...
```
The new one removes the double reference to the url data via URLValue, and looks
like:
```
SpecifiedUrl
* CssUrl
* Arc<CssUrlData>
* String
* UrlExtraData
* CorsMode
* LoadData
* load id
* resolved URI
```
The LoadData is the only mutable bit that C++ can change, and is not used from
Rust. Ideally, in the future, we could just use rust-url to resolve the URL
after parsing or something, and make it all immutable. Maybe.
I've verified that this approach still works with the UA sheet patches (via the
LoadDataSource::Lazy).
The reordering of mWillChange is to avoid nsStyleDisplay from going over the
size limit. We want to split it up anyway in bug 1552587, but mBinding gains a
tag member, which means that we were having a bit of extra padding.
One thing I want to explore is to see if we can abuse rustc's non-zero
optimizations to predict the layout from C++, but that's something to explore at
some other point in time and with a lot of care and help from Michael (who sits
next to me and works on rustc ;)).
Differential Revision: https://phabricator.services.mozilla.com/D31742
2019-05-27 14:45:12 +03:00
|
|
|
imgRequestProxy* request = mImageURL.LoadImage(aDocument);
|
2019-02-02 21:42:25 +03:00
|
|
|
bool isPrint = !!aDocument.GetOriginalDocument();
|
|
|
|
if (!isPrint) {
|
2018-05-22 14:34:17 +03:00
|
|
|
mRequestProxy = request;
|
|
|
|
} else if (request) {
|
2019-02-02 21:42:25 +03:00
|
|
|
request->GetStaticRequest(&aDocument, getter_AddRefs(mRequestProxy));
|
2018-05-22 14:34:17 +03:00
|
|
|
}
|
2018-02-22 22:03:43 +03:00
|
|
|
}
|
2016-11-02 11:58:31 +03:00
|
|
|
|
|
|
|
if (!mRequestProxy) {
|
|
|
|
// The URL resolution or image load failed.
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2019-03-28 05:54:16 +03:00
|
|
|
// Boost priority now that we know the image is present in the ComputedStyle
|
|
|
|
// of some frame.
|
|
|
|
mRequestProxy->BoostPriority(imgIRequest::CATEGORY_FRAME_STYLE);
|
|
|
|
|
2016-11-02 11:58:32 +03:00
|
|
|
if (mModeFlags & Mode::Track) {
|
2019-02-02 21:42:25 +03:00
|
|
|
mImageTracker = aDocument.ImageTracker();
|
2016-11-02 11:58:32 +03:00
|
|
|
}
|
|
|
|
|
2016-11-02 11:58:31 +03:00
|
|
|
MaybeTrackAndLock();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void nsStyleImageRequest::MaybeTrackAndLock() {
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
MOZ_ASSERT(IsResolved());
|
|
|
|
MOZ_ASSERT(mRequestProxy);
|
|
|
|
|
|
|
|
if (mModeFlags & Mode::Track) {
|
2016-11-02 11:58:32 +03:00
|
|
|
MOZ_ASSERT(mImageTracker);
|
2016-11-02 11:58:31 +03:00
|
|
|
mImageTracker->Add(mRequestProxy);
|
2016-11-02 11:58:32 +03:00
|
|
|
} else {
|
|
|
|
MOZ_ASSERT(!mImageTracker);
|
2016-11-02 11:58:31 +03:00
|
|
|
mRequestProxy->LockImage();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool nsStyleImageRequest::DefinitelyEquals(
|
|
|
|
const nsStyleImageRequest& aOther) const {
|
Bug 1552708 - Use cbindgen for URIs. r=heycam
This doesn't clean up as much as a whole, but it's a step in the right
direction. In particular, it allows us to start using simple bindings for:
* Filters
* Shapes and images, almost. Need to:
* Get rid of the complex -moz- gradient parsing (let
layout.css.simple-moz-gradient.enabled get to release).
* Counters, almost. Need to:
* Share the Attr representation with Gecko, by not using Option<>.
* Just another variant should be enough (ContentItem::{Attr,Prefixedattr},
maybe).
Which in turn allows us to remove a whole lot of bindings in followups to this.
The setup changes a bit. This also removes the double pointer I complained about
while reviewing the shared UA sheet patches. The old setup is:
```
SpecifiedUrl
* CssUrl
* Arc<CssUrlData>
* String
* UrlExtraData
* UrlValueSource
* Arc<CssUrlData>
* load id
* resolved uri
* CORS mode.
* ...
```
The new one removes the double reference to the url data via URLValue, and looks
like:
```
SpecifiedUrl
* CssUrl
* Arc<CssUrlData>
* String
* UrlExtraData
* CorsMode
* LoadData
* load id
* resolved URI
```
The LoadData is the only mutable bit that C++ can change, and is not used from
Rust. Ideally, in the future, we could just use rust-url to resolve the URL
after parsing or something, and make it all immutable. Maybe.
I've verified that this approach still works with the UA sheet patches (via the
LoadDataSource::Lazy).
The reordering of mWillChange is to avoid nsStyleDisplay from going over the
size limit. We want to split it up anyway in bug 1552587, but mBinding gains a
tag member, which means that we were having a bit of extra padding.
One thing I want to explore is to see if we can abuse rustc's non-zero
optimizations to predict the layout from C++, but that's something to explore at
some other point in time and with a lot of care and help from Michael (who sits
next to me and works on rustc ;)).
Differential Revision: https://phabricator.services.mozilla.com/D31742
2019-05-27 14:45:12 +03:00
|
|
|
return mImageURL == aOther.mImageURL;
|
2016-11-02 11:58:31 +03:00
|
|
|
}
|
|
|
|
|
2016-08-01 03:23:00 +03:00
|
|
|
// --------------------
|
|
|
|
// CachedBorderImageData
|
|
|
|
//
|
2016-08-01 03:24:00 +03:00
|
|
|
void CachedBorderImageData::SetCachedSVGViewportSize(
|
|
|
|
const mozilla::Maybe<nsSize>& aSVGViewportSize) {
|
|
|
|
mCachedSVGViewportSize = aSVGViewportSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
const mozilla::Maybe<nsSize>&
|
|
|
|
CachedBorderImageData::GetCachedSVGViewportSize() {
|
|
|
|
return mCachedSVGViewportSize;
|
|
|
|
}
|
|
|
|
|
2017-02-20 15:39:05 +03:00
|
|
|
struct PurgeCachedImagesTask : mozilla::Runnable {
|
2017-06-12 22:34:10 +03:00
|
|
|
PurgeCachedImagesTask() : mozilla::Runnable("PurgeCachedImagesTask") {}
|
2018-02-06 09:46:57 +03:00
|
|
|
NS_IMETHOD Run() final {
|
2017-02-20 15:39:05 +03:00
|
|
|
mSubImages.Clear();
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMArray<imgIContainer> mSubImages;
|
|
|
|
};
|
|
|
|
|
2016-08-01 03:23:00 +03:00
|
|
|
void CachedBorderImageData::PurgeCachedImages() {
|
2017-02-20 15:39:05 +03:00
|
|
|
if (ServoStyleSet::IsInServoTraversal()) {
|
|
|
|
RefPtr<PurgeCachedImagesTask> task = new PurgeCachedImagesTask();
|
|
|
|
task->mSubImages.SwapElements(mSubImages);
|
|
|
|
// This will run the task immediately if we're already on the main thread,
|
|
|
|
// but that is fine.
|
|
|
|
NS_DispatchToMainThread(task.forget());
|
|
|
|
} else {
|
|
|
|
mSubImages.Clear();
|
|
|
|
}
|
2016-08-01 03:23:00 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void CachedBorderImageData::SetSubImage(uint8_t aIndex,
|
|
|
|
imgIContainer* aSubImage) {
|
|
|
|
mSubImages.ReplaceObjectAt(aSubImage, aIndex);
|
|
|
|
}
|
|
|
|
|
|
|
|
imgIContainer* CachedBorderImageData::GetSubImage(uint8_t aIndex) {
|
|
|
|
imgIContainer* subImage = nullptr;
|
|
|
|
if (aIndex < mSubImages.Count()) subImage = mSubImages[aIndex];
|
|
|
|
return subImage;
|
|
|
|
}
|
|
|
|
|
2009-08-22 00:39:25 +04:00
|
|
|
// --------------------
|
|
|
|
// nsStyleImage
|
|
|
|
//
|
|
|
|
|
|
|
|
nsStyleImage::nsStyleImage()
|
|
|
|
: mType(eStyleImageType_Null), mImage(nullptr), mCropRect(nullptr) {
|
|
|
|
MOZ_COUNT_CTOR(nsStyleImage);
|
|
|
|
}
|
|
|
|
|
|
|
|
nsStyleImage::~nsStyleImage() {
|
|
|
|
MOZ_COUNT_DTOR(nsStyleImage);
|
2016-07-06 08:06:13 +03:00
|
|
|
if (mType != eStyleImageType_Null) {
|
2009-08-22 00:39:25 +04:00
|
|
|
SetNull();
|
2016-07-06 08:06:13 +03:00
|
|
|
}
|
2009-08-22 00:39:25 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
nsStyleImage::nsStyleImage(const nsStyleImage& aOther)
|
|
|
|
: mType(eStyleImageType_Null), mCropRect(nullptr) {
|
|
|
|
// We need our own copy constructor because we don't want
|
|
|
|
// to copy the reference count
|
|
|
|
MOZ_COUNT_CTOR(nsStyleImage);
|
|
|
|
DoCopy(aOther);
|
|
|
|
}
|
|
|
|
|
|
|
|
nsStyleImage& nsStyleImage::operator=(const nsStyleImage& aOther) {
|
2016-07-06 08:06:13 +03:00
|
|
|
if (this != &aOther) {
|
2009-08-22 00:39:25 +04:00
|
|
|
DoCopy(aOther);
|
2016-07-06 08:06:13 +03:00
|
|
|
}
|
2009-08-22 00:39:25 +04:00
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
void nsStyleImage::DoCopy(const nsStyleImage& aOther) {
|
|
|
|
SetNull();
|
|
|
|
|
2016-07-06 08:06:13 +03:00
|
|
|
if (aOther.mType == eStyleImageType_Image) {
|
2016-11-02 11:58:32 +03:00
|
|
|
SetImageRequest(do_AddRef(aOther.mImage));
|
2016-07-06 08:06:13 +03:00
|
|
|
} else if (aOther.mType == eStyleImageType_Gradient) {
|
2019-06-07 17:13:17 +03:00
|
|
|
SetGradientData(MakeUnique<StyleGradient>(*aOther.mGradient));
|
2016-07-06 08:06:13 +03:00
|
|
|
} else if (aOther.mType == eStyleImageType_Element) {
|
2017-04-09 16:44:36 +03:00
|
|
|
SetElementId(do_AddRef(aOther.mElementId));
|
2016-07-06 08:06:13 +03:00
|
|
|
}
|
2009-08-22 00:39:25 +04:00
|
|
|
|
2016-07-29 01:06:02 +03:00
|
|
|
UniquePtr<nsStyleSides> cropRectCopy;
|
|
|
|
if (aOther.mCropRect) {
|
|
|
|
cropRectCopy = MakeUnique<nsStyleSides>(*aOther.mCropRect.get());
|
|
|
|
}
|
2018-05-30 22:15:35 +03:00
|
|
|
SetCropRect(std::move(cropRectCopy));
|
2009-08-22 00:39:25 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void nsStyleImage::SetNull() {
|
2016-07-06 08:06:13 +03:00
|
|
|
if (mType == eStyleImageType_Gradient) {
|
2019-06-07 17:13:17 +03:00
|
|
|
delete mGradient;
|
|
|
|
mGradient = nullptr;
|
2016-07-06 08:06:13 +03:00
|
|
|
} else if (mType == eStyleImageType_Image) {
|
2009-08-22 00:39:25 +04:00
|
|
|
NS_RELEASE(mImage);
|
2016-07-06 08:06:13 +03:00
|
|
|
} else if (mType == eStyleImageType_Element) {
|
2017-04-09 16:44:36 +03:00
|
|
|
NS_RELEASE(mElementId);
|
2016-07-06 08:06:13 +03:00
|
|
|
}
|
2009-08-22 00:39:25 +04:00
|
|
|
|
|
|
|
mType = eStyleImageType_Null;
|
2012-07-30 18:20:58 +04:00
|
|
|
mCropRect = nullptr;
|
2009-08-22 00:39:25 +04:00
|
|
|
}
|
|
|
|
|
2016-11-02 11:58:32 +03:00
|
|
|
void nsStyleImage::SetImageRequest(
|
|
|
|
already_AddRefed<nsStyleImageRequest> aImage) {
|
|
|
|
RefPtr<nsStyleImageRequest> image = aImage;
|
2009-08-22 00:39:25 +04:00
|
|
|
|
2016-07-06 08:06:13 +03:00
|
|
|
if (mType != eStyleImageType_Null) {
|
2009-08-22 00:39:25 +04:00
|
|
|
SetNull();
|
2016-07-06 08:06:13 +03:00
|
|
|
}
|
2009-08-22 00:39:25 +04:00
|
|
|
|
2016-11-02 11:58:32 +03:00
|
|
|
if (image) {
|
|
|
|
mImage = image.forget().take();
|
2009-08-22 00:39:25 +04:00
|
|
|
mType = eStyleImageType_Image;
|
|
|
|
}
|
2016-08-01 03:23:00 +03:00
|
|
|
if (mCachedBIData) {
|
|
|
|
mCachedBIData->PurgeCachedImages();
|
|
|
|
}
|
2009-08-22 00:39:25 +04:00
|
|
|
}
|
|
|
|
|
2019-06-07 17:13:17 +03:00
|
|
|
void nsStyleImage::SetGradientData(UniquePtr<StyleGradient> aGradient) {
|
|
|
|
MOZ_ASSERT(aGradient);
|
2009-08-22 00:39:25 +04:00
|
|
|
|
2016-07-06 08:06:13 +03:00
|
|
|
if (mType != eStyleImageType_Null) {
|
2009-08-22 00:39:25 +04:00
|
|
|
SetNull();
|
2016-07-06 08:06:13 +03:00
|
|
|
}
|
2009-08-22 00:39:25 +04:00
|
|
|
|
2019-06-07 17:13:17 +03:00
|
|
|
mGradient = aGradient.release();
|
|
|
|
mType = eStyleImageType_Gradient;
|
2009-08-22 00:39:25 +04:00
|
|
|
}
|
|
|
|
|
2017-10-03 01:05:19 +03:00
|
|
|
void nsStyleImage::SetElementId(already_AddRefed<nsAtom> aElementId) {
|
2016-07-06 08:06:13 +03:00
|
|
|
if (mType != eStyleImageType_Null) {
|
2010-08-13 17:33:37 +04:00
|
|
|
SetNull();
|
2016-07-06 08:06:13 +03:00
|
|
|
}
|
2010-08-13 17:33:37 +04:00
|
|
|
|
2017-10-03 01:05:19 +03:00
|
|
|
if (RefPtr<nsAtom> atom = aElementId) {
|
2017-04-09 16:44:36 +03:00
|
|
|
mElementId = atom.forget().take();
|
2010-08-13 17:33:37 +04:00
|
|
|
mType = eStyleImageType_Element;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-07-29 01:06:02 +03:00
|
|
|
void nsStyleImage::SetCropRect(UniquePtr<nsStyleSides> aCropRect) {
|
2018-05-30 22:15:35 +03:00
|
|
|
mCropRect = std::move(aCropRect);
|
2009-08-22 00:39:25 +04:00
|
|
|
}
|
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
static int32_t ConvertToPixelCoord(const nsStyleCoord& aCoord,
|
|
|
|
int32_t aPercentScale) {
|
2009-08-22 00:39:25 +04:00
|
|
|
double pixelValue;
|
|
|
|
switch (aCoord.GetUnit()) {
|
|
|
|
case eStyleUnit_Percent:
|
|
|
|
pixelValue = aCoord.GetPercentValue() * aPercentScale;
|
|
|
|
break;
|
|
|
|
case eStyleUnit_Factor:
|
|
|
|
pixelValue = aCoord.GetFactorValue();
|
|
|
|
break;
|
|
|
|
default:
|
2018-06-18 08:43:11 +03:00
|
|
|
MOZ_ASSERT_UNREACHABLE("unexpected unit for image crop rect");
|
2009-08-22 00:39:25 +04:00
|
|
|
return 0;
|
|
|
|
}
|
2015-02-10 01:34:50 +03:00
|
|
|
MOZ_ASSERT(pixelValue >= 0, "we ensured non-negative while parsing");
|
2013-01-15 16:22:03 +04:00
|
|
|
pixelValue = std::min(pixelValue, double(INT32_MAX)); // avoid overflow
|
2009-08-22 00:39:25 +04:00
|
|
|
return NS_lround(pixelValue);
|
|
|
|
}
|
|
|
|
|
2017-03-09 08:03:32 +03:00
|
|
|
already_AddRefed<nsIURI> nsStyleImageRequest::GetImageURI() const {
|
|
|
|
nsCOMPtr<nsIURI> uri;
|
|
|
|
|
|
|
|
if (mRequestProxy) {
|
|
|
|
mRequestProxy->GetURI(getter_AddRefs(uri));
|
|
|
|
if (uri) {
|
|
|
|
return uri.forget();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we had some problem resolving the mRequestProxy, use the URL stored
|
Bug 1552708 - Use cbindgen for URIs. r=heycam
This doesn't clean up as much as a whole, but it's a step in the right
direction. In particular, it allows us to start using simple bindings for:
* Filters
* Shapes and images, almost. Need to:
* Get rid of the complex -moz- gradient parsing (let
layout.css.simple-moz-gradient.enabled get to release).
* Counters, almost. Need to:
* Share the Attr representation with Gecko, by not using Option<>.
* Just another variant should be enough (ContentItem::{Attr,Prefixedattr},
maybe).
Which in turn allows us to remove a whole lot of bindings in followups to this.
The setup changes a bit. This also removes the double pointer I complained about
while reviewing the shared UA sheet patches. The old setup is:
```
SpecifiedUrl
* CssUrl
* Arc<CssUrlData>
* String
* UrlExtraData
* UrlValueSource
* Arc<CssUrlData>
* load id
* resolved uri
* CORS mode.
* ...
```
The new one removes the double reference to the url data via URLValue, and looks
like:
```
SpecifiedUrl
* CssUrl
* Arc<CssUrlData>
* String
* UrlExtraData
* CorsMode
* LoadData
* load id
* resolved URI
```
The LoadData is the only mutable bit that C++ can change, and is not used from
Rust. Ideally, in the future, we could just use rust-url to resolve the URL
after parsing or something, and make it all immutable. Maybe.
I've verified that this approach still works with the UA sheet patches (via the
LoadDataSource::Lazy).
The reordering of mWillChange is to avoid nsStyleDisplay from going over the
size limit. We want to split it up anyway in bug 1552587, but mBinding gains a
tag member, which means that we were having a bit of extra padding.
One thing I want to explore is to see if we can abuse rustc's non-zero
optimizations to predict the layout from C++, but that's something to explore at
some other point in time and with a lot of care and help from Michael (who sits
next to me and works on rustc ;)).
Differential Revision: https://phabricator.services.mozilla.com/D31742
2019-05-27 14:45:12 +03:00
|
|
|
// in the mImageURL.
|
|
|
|
uri = mImageURL.GetURI();
|
2017-03-09 08:03:32 +03:00
|
|
|
return uri.forget();
|
|
|
|
}
|
|
|
|
|
2009-08-22 00:39:25 +04:00
|
|
|
bool nsStyleImage::ComputeActualCropRect(nsIntRect& aActualCropRect,
|
2011-09-29 10:19:26 +04:00
|
|
|
bool* aIsEntireImage) const {
|
2017-04-21 22:28:20 +03:00
|
|
|
MOZ_ASSERT(mType == eStyleImageType_Image,
|
|
|
|
"This function is designed to be used only when mType"
|
|
|
|
"is eStyleImageType_Image.");
|
2009-08-22 00:39:25 +04:00
|
|
|
|
2016-11-02 11:58:32 +03:00
|
|
|
imgRequestProxy* req = GetImageData();
|
|
|
|
if (!req) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2009-08-22 00:39:25 +04:00
|
|
|
nsCOMPtr<imgIContainer> imageContainer;
|
2016-11-02 11:58:32 +03:00
|
|
|
req->GetImage(getter_AddRefs(imageContainer));
|
2016-07-06 08:06:13 +03:00
|
|
|
if (!imageContainer) {
|
2011-10-17 18:59:28 +04:00
|
|
|
return false;
|
2016-07-06 08:06:13 +03:00
|
|
|
}
|
2009-08-22 00:39:25 +04:00
|
|
|
|
|
|
|
nsIntSize imageSize;
|
|
|
|
imageContainer->GetWidth(&imageSize.width);
|
|
|
|
imageContainer->GetHeight(&imageSize.height);
|
2016-07-06 08:06:13 +03:00
|
|
|
if (imageSize.width <= 0 || imageSize.height <= 0) {
|
2011-10-17 18:59:28 +04:00
|
|
|
return false;
|
2016-07-06 08:06:13 +03:00
|
|
|
}
|
2009-08-22 00:39:25 +04:00
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
int32_t left = ConvertToPixelCoord(mCropRect->GetLeft(), imageSize.width);
|
|
|
|
int32_t top = ConvertToPixelCoord(mCropRect->GetTop(), imageSize.height);
|
|
|
|
int32_t right = ConvertToPixelCoord(mCropRect->GetRight(), imageSize.width);
|
|
|
|
int32_t bottom =
|
|
|
|
ConvertToPixelCoord(mCropRect->GetBottom(), imageSize.height);
|
2009-08-22 00:39:25 +04:00
|
|
|
|
|
|
|
// IntersectRect() returns an empty rect if we get negative width or height
|
|
|
|
nsIntRect cropRect(left, top, right - left, bottom - top);
|
|
|
|
nsIntRect imageRect(nsIntPoint(0, 0), imageSize);
|
|
|
|
aActualCropRect.IntersectRect(imageRect, cropRect);
|
|
|
|
|
2016-07-06 08:06:13 +03:00
|
|
|
if (aIsEntireImage) {
|
2011-04-19 07:07:23 +04:00
|
|
|
*aIsEntireImage = aActualCropRect.IsEqualInterior(imageRect);
|
2016-07-06 08:06:13 +03:00
|
|
|
}
|
2011-10-17 18:59:28 +04:00
|
|
|
return true;
|
2009-08-22 00:39:25 +04:00
|
|
|
}
|
|
|
|
|
2012-10-13 00:04:03 +04:00
|
|
|
bool nsStyleImage::StartDecoding() const {
|
2016-08-15 04:57:13 +03:00
|
|
|
if (mType == eStyleImageType_Image) {
|
2016-11-02 11:58:32 +03:00
|
|
|
imgRequestProxy* req = GetImageData();
|
|
|
|
if (!req) {
|
2016-12-23 10:07:45 +03:00
|
|
|
return false;
|
2016-11-02 11:58:32 +03:00
|
|
|
}
|
2016-12-25 09:18:08 +03:00
|
|
|
return req->StartDecodingWithResult(imgIContainer::FLAG_ASYNC_NOTIFY);
|
2016-07-06 08:06:13 +03:00
|
|
|
}
|
2016-12-23 10:07:45 +03:00
|
|
|
// null image types always return false from IsComplete, so we do the same
|
|
|
|
// here.
|
|
|
|
return mType != eStyleImageType_Null ? true : false;
|
2009-09-13 02:44:18 +04:00
|
|
|
}
|
|
|
|
|
2009-08-22 00:39:25 +04:00
|
|
|
bool nsStyleImage::IsOpaque() const {
|
2016-07-06 08:06:13 +03:00
|
|
|
if (!IsComplete()) {
|
2011-10-17 18:59:28 +04:00
|
|
|
return false;
|
2016-07-06 08:06:13 +03:00
|
|
|
}
|
2009-08-22 00:39:25 +04:00
|
|
|
|
2016-07-06 08:06:13 +03:00
|
|
|
if (mType == eStyleImageType_Gradient) {
|
2011-01-03 04:48:09 +03:00
|
|
|
return mGradient->IsOpaque();
|
2016-07-06 08:06:13 +03:00
|
|
|
}
|
2009-08-22 00:39:25 +04:00
|
|
|
|
2019-05-22 14:34:23 +03:00
|
|
|
if (mType == eStyleImageType_Element) {
|
2011-10-17 18:59:28 +04:00
|
|
|
return false;
|
2016-07-06 08:06:13 +03:00
|
|
|
}
|
2010-08-13 17:33:37 +04:00
|
|
|
|
2015-02-10 01:34:50 +03:00
|
|
|
MOZ_ASSERT(mType == eStyleImageType_Image, "unexpected image type");
|
2016-11-02 11:58:32 +03:00
|
|
|
MOZ_ASSERT(GetImageData(), "should've returned earlier above");
|
2009-08-22 00:39:25 +04:00
|
|
|
|
|
|
|
nsCOMPtr<imgIContainer> imageContainer;
|
2016-11-02 11:58:32 +03:00
|
|
|
GetImageData()->GetImage(getter_AddRefs(imageContainer));
|
2015-02-10 01:34:50 +03:00
|
|
|
MOZ_ASSERT(imageContainer, "IsComplete() said image container is ready");
|
2009-08-22 00:39:25 +04:00
|
|
|
|
2014-11-25 10:42:43 +03:00
|
|
|
// Check if the crop region of the image is opaque.
|
2016-08-23 05:15:38 +03:00
|
|
|
if (imageContainer->WillDrawOpaqueNow()) {
|
2016-07-06 08:06:13 +03:00
|
|
|
if (!mCropRect) {
|
2011-10-17 18:59:28 +04:00
|
|
|
return true;
|
2016-07-06 08:06:13 +03:00
|
|
|
}
|
2009-08-22 00:39:25 +04:00
|
|
|
|
|
|
|
// Must make sure if mCropRect contains at least a pixel.
|
2011-10-17 18:59:28 +04:00
|
|
|
// XXX Is this optimization worth it? Maybe I should just return false.
|
2009-08-22 00:39:25 +04:00
|
|
|
nsIntRect actualCropRect;
|
2017-04-21 22:28:20 +03:00
|
|
|
return ComputeActualCropRect(actualCropRect) && !actualCropRect.IsEmpty();
|
2009-08-22 00:39:25 +04:00
|
|
|
}
|
|
|
|
|
2011-10-17 18:59:28 +04:00
|
|
|
return false;
|
2009-08-22 00:39:25 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
bool nsStyleImage::IsComplete() const {
|
|
|
|
switch (mType) {
|
|
|
|
case eStyleImageType_Null:
|
2011-10-17 18:59:28 +04:00
|
|
|
return false;
|
2009-08-22 00:39:25 +04:00
|
|
|
case eStyleImageType_Gradient:
|
2010-08-13 17:33:37 +04:00
|
|
|
case eStyleImageType_Element:
|
2011-10-17 18:59:28 +04:00
|
|
|
return true;
|
2016-11-02 11:58:32 +03:00
|
|
|
case eStyleImageType_Image: {
|
2017-07-26 06:21:30 +03:00
|
|
|
if (!IsResolved()) {
|
|
|
|
return false;
|
|
|
|
}
|
2016-11-02 11:58:32 +03:00
|
|
|
imgRequestProxy* req = GetImageData();
|
|
|
|
if (!req) {
|
|
|
|
return false;
|
|
|
|
}
|
2012-08-22 19:56:38 +04:00
|
|
|
uint32_t status = imgIRequest::STATUS_ERROR;
|
2016-11-02 11:58:32 +03:00
|
|
|
return NS_SUCCEEDED(req->GetImageStatus(&status)) &&
|
2009-08-22 00:39:25 +04:00
|
|
|
(status & imgIRequest::STATUS_SIZE_AVAILABLE) &&
|
|
|
|
(status & imgIRequest::STATUS_FRAME_COMPLETE);
|
|
|
|
}
|
|
|
|
default:
|
2018-06-18 08:43:11 +03:00
|
|
|
MOZ_ASSERT_UNREACHABLE("unexpected image type");
|
2011-10-17 18:59:28 +04:00
|
|
|
return false;
|
2009-08-22 00:39:25 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-07-19 12:40:02 +04:00
|
|
|
bool nsStyleImage::IsLoaded() const {
|
|
|
|
switch (mType) {
|
|
|
|
case eStyleImageType_Null:
|
|
|
|
return false;
|
|
|
|
case eStyleImageType_Gradient:
|
|
|
|
case eStyleImageType_Element:
|
|
|
|
return true;
|
2016-11-02 11:58:32 +03:00
|
|
|
case eStyleImageType_Image: {
|
|
|
|
imgRequestProxy* req = GetImageData();
|
|
|
|
if (!req) {
|
|
|
|
return false;
|
|
|
|
}
|
2013-07-19 12:40:02 +04:00
|
|
|
uint32_t status = imgIRequest::STATUS_ERROR;
|
2016-11-02 11:58:32 +03:00
|
|
|
return NS_SUCCEEDED(req->GetImageStatus(&status)) &&
|
2013-07-19 12:40:02 +04:00
|
|
|
!(status & imgIRequest::STATUS_ERROR) &&
|
|
|
|
(status & imgIRequest::STATUS_LOAD_COMPLETE);
|
|
|
|
}
|
|
|
|
default:
|
2018-06-18 08:43:11 +03:00
|
|
|
MOZ_ASSERT_UNREACHABLE("unexpected image type");
|
2013-07-19 12:40:02 +04:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-07-29 01:06:02 +03:00
|
|
|
static inline bool EqualRects(const UniquePtr<nsStyleSides>& aRect1,
|
|
|
|
const UniquePtr<nsStyleSides>& aRect2) {
|
2009-08-22 00:39:25 +04:00
|
|
|
return aRect1 == aRect2 || /* handles null== null, and optimize */
|
|
|
|
(aRect1 && aRect2 && *aRect1 == *aRect2);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool nsStyleImage::operator==(const nsStyleImage& aOther) const {
|
2016-07-06 08:06:13 +03:00
|
|
|
if (mType != aOther.mType) {
|
2011-10-17 18:59:28 +04:00
|
|
|
return false;
|
2016-07-06 08:06:13 +03:00
|
|
|
}
|
2009-08-22 00:39:25 +04:00
|
|
|
|
2016-07-06 08:06:13 +03:00
|
|
|
if (!EqualRects(mCropRect, aOther.mCropRect)) {
|
2011-10-17 18:59:28 +04:00
|
|
|
return false;
|
2016-07-06 08:06:13 +03:00
|
|
|
}
|
2009-08-22 00:39:25 +04:00
|
|
|
|
2016-07-06 08:06:13 +03:00
|
|
|
if (mType == eStyleImageType_Image) {
|
2016-11-02 11:58:32 +03:00
|
|
|
return DefinitelyEqualImages(mImage, aOther.mImage);
|
2016-07-06 08:06:13 +03:00
|
|
|
}
|
2009-08-22 00:39:25 +04:00
|
|
|
|
2016-07-06 08:06:13 +03:00
|
|
|
if (mType == eStyleImageType_Gradient) {
|
2009-08-22 00:39:25 +04:00
|
|
|
return *mGradient == *aOther.mGradient;
|
2016-07-06 08:06:13 +03:00
|
|
|
}
|
2009-08-22 00:39:25 +04:00
|
|
|
|
2016-07-06 08:06:13 +03:00
|
|
|
if (mType == eStyleImageType_Element) {
|
2017-04-09 16:44:36 +03:00
|
|
|
return mElementId == aOther.mElementId;
|
2016-07-06 08:06:13 +03:00
|
|
|
}
|
2010-08-13 17:33:37 +04:00
|
|
|
|
2011-10-17 18:59:28 +04:00
|
|
|
return true;
|
2009-08-22 00:39:25 +04:00
|
|
|
}
|
|
|
|
|
2016-08-01 03:24:00 +03:00
|
|
|
void nsStyleImage::PurgeCacheForViewportChange(
|
|
|
|
const mozilla::Maybe<nsSize>& aSVGViewportSize,
|
|
|
|
const bool aHasIntrinsicRatio) const {
|
|
|
|
EnsureCachedBIData();
|
|
|
|
|
|
|
|
// If we're redrawing with a different viewport-size than we used for our
|
|
|
|
// cached subimages, then we can't trust that our subimages are valid;
|
|
|
|
// any percent sizes/positions in our SVG doc may be different now. Purge!
|
|
|
|
// (We don't have to purge if the SVG document has an intrinsic ratio,
|
|
|
|
// though, because the actual size of elements in SVG documant's coordinate
|
|
|
|
// axis are fixed in this case.)
|
|
|
|
if (aSVGViewportSize != mCachedBIData->GetCachedSVGViewportSize() &&
|
|
|
|
!aHasIntrinsicRatio) {
|
|
|
|
mCachedBIData->PurgeCachedImages();
|
|
|
|
mCachedBIData->SetCachedSVGViewportSize(aSVGViewportSize);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-03-09 08:03:32 +03:00
|
|
|
already_AddRefed<nsIURI> nsStyleImage::GetImageURI() const {
|
|
|
|
if (mType != eStyleImageType_Image) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIURI> uri = mImage->GetImageURI();
|
|
|
|
return uri.forget();
|
|
|
|
}
|
|
|
|
|
Bug 1552708 - Use cbindgen for URIs. r=heycam
This doesn't clean up as much as a whole, but it's a step in the right
direction. In particular, it allows us to start using simple bindings for:
* Filters
* Shapes and images, almost. Need to:
* Get rid of the complex -moz- gradient parsing (let
layout.css.simple-moz-gradient.enabled get to release).
* Counters, almost. Need to:
* Share the Attr representation with Gecko, by not using Option<>.
* Just another variant should be enough (ContentItem::{Attr,Prefixedattr},
maybe).
Which in turn allows us to remove a whole lot of bindings in followups to this.
The setup changes a bit. This also removes the double pointer I complained about
while reviewing the shared UA sheet patches. The old setup is:
```
SpecifiedUrl
* CssUrl
* Arc<CssUrlData>
* String
* UrlExtraData
* UrlValueSource
* Arc<CssUrlData>
* load id
* resolved uri
* CORS mode.
* ...
```
The new one removes the double reference to the url data via URLValue, and looks
like:
```
SpecifiedUrl
* CssUrl
* Arc<CssUrlData>
* String
* UrlExtraData
* CorsMode
* LoadData
* load id
* resolved URI
```
The LoadData is the only mutable bit that C++ can change, and is not used from
Rust. Ideally, in the future, we could just use rust-url to resolve the URL
after parsing or something, and make it all immutable. Maybe.
I've verified that this approach still works with the UA sheet patches (via the
LoadDataSource::Lazy).
The reordering of mWillChange is to avoid nsStyleDisplay from going over the
size limit. We want to split it up anyway in bug 1552587, but mBinding gains a
tag member, which means that we were having a bit of extra padding.
One thing I want to explore is to see if we can abuse rustc's non-zero
optimizations to predict the layout from C++, but that's something to explore at
some other point in time and with a lot of care and help from Michael (who sits
next to me and works on rustc ;)).
Differential Revision: https://phabricator.services.mozilla.com/D31742
2019-05-27 14:45:12 +03:00
|
|
|
const StyleComputedImageUrl* nsStyleImage::GetURLValue() const {
|
|
|
|
return mType == eStyleImageType_Image ? &mImage->GetImageValue() : nullptr;
|
2017-03-30 18:16:46 +03:00
|
|
|
}
|
|
|
|
|
2001-06-01 02:19:43 +04:00
|
|
|
// --------------------
|
2016-01-28 08:24:00 +03:00
|
|
|
// nsStyleImageLayers
|
2001-06-01 02:19:43 +04:00
|
|
|
//
|
|
|
|
|
2016-08-17 04:37:48 +03:00
|
|
|
const nsCSSPropertyID nsStyleImageLayers::kBackgroundLayerTable[] = {
|
2016-01-28 08:28:00 +03:00
|
|
|
eCSSProperty_background, // shorthand
|
|
|
|
eCSSProperty_background_color, // color
|
|
|
|
eCSSProperty_background_image, // image
|
|
|
|
eCSSProperty_background_repeat, // repeat
|
2016-04-29 21:12:10 +03:00
|
|
|
eCSSProperty_background_position_x, // positionX
|
|
|
|
eCSSProperty_background_position_y, // positionY
|
2016-01-28 08:28:00 +03:00
|
|
|
eCSSProperty_background_clip, // clip
|
|
|
|
eCSSProperty_background_origin, // origin
|
|
|
|
eCSSProperty_background_size, // size
|
|
|
|
eCSSProperty_background_attachment, // attachment
|
|
|
|
eCSSProperty_UNKNOWN, // maskMode
|
|
|
|
eCSSProperty_UNKNOWN // composite
|
|
|
|
};
|
|
|
|
|
2016-08-17 04:37:48 +03:00
|
|
|
const nsCSSPropertyID nsStyleImageLayers::kMaskLayerTable[] = {
|
2016-01-28 08:28:00 +03:00
|
|
|
eCSSProperty_mask, // shorthand
|
|
|
|
eCSSProperty_UNKNOWN, // color
|
|
|
|
eCSSProperty_mask_image, // image
|
|
|
|
eCSSProperty_mask_repeat, // repeat
|
2016-04-29 21:12:10 +03:00
|
|
|
eCSSProperty_mask_position_x, // positionX
|
|
|
|
eCSSProperty_mask_position_y, // positionY
|
2016-01-28 08:28:00 +03:00
|
|
|
eCSSProperty_mask_clip, // clip
|
|
|
|
eCSSProperty_mask_origin, // origin
|
|
|
|
eCSSProperty_mask_size, // size
|
|
|
|
eCSSProperty_UNKNOWN, // attachment
|
|
|
|
eCSSProperty_mask_mode, // maskMode
|
|
|
|
eCSSProperty_mask_composite // composite
|
|
|
|
};
|
|
|
|
|
2016-06-03 18:56:54 +03:00
|
|
|
nsStyleImageLayers::nsStyleImageLayers(nsStyleImageLayers::LayerType aType)
|
2009-02-20 08:29:21 +03:00
|
|
|
: mAttachmentCount(1),
|
|
|
|
mClipCount(1),
|
|
|
|
mOriginCount(1),
|
|
|
|
mRepeatCount(1),
|
2016-04-29 21:12:10 +03:00
|
|
|
mPositionXCount(1),
|
|
|
|
mPositionYCount(1),
|
2009-02-20 08:29:21 +03:00
|
|
|
mImageCount(1),
|
2009-05-28 22:09:05 +04:00
|
|
|
mSizeCount(1),
|
2016-01-28 08:28:00 +03:00
|
|
|
mMaskModeCount(1),
|
2013-11-08 19:07:36 +04:00
|
|
|
mBlendModeCount(1),
|
2016-01-28 08:28:00 +03:00
|
|
|
mCompositeCount(1),
|
2016-04-19 02:51:16 +03:00
|
|
|
mLayers(nsStyleAutoArray<Layer>::WITH_SINGLE_INITIAL_ELEMENT) {
|
2016-01-28 08:24:00 +03:00
|
|
|
MOZ_COUNT_CTOR(nsStyleImageLayers);
|
2016-06-03 18:56:54 +03:00
|
|
|
|
|
|
|
// Ensure first layer is initialized as specified layer type
|
|
|
|
mLayers[0].Initialize(aType);
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
|
|
|
|
2016-01-28 08:24:00 +03:00
|
|
|
nsStyleImageLayers::nsStyleImageLayers(const nsStyleImageLayers& aSource)
|
2009-02-20 08:29:21 +03:00
|
|
|
: mAttachmentCount(aSource.mAttachmentCount),
|
|
|
|
mClipCount(aSource.mClipCount),
|
|
|
|
mOriginCount(aSource.mOriginCount),
|
|
|
|
mRepeatCount(aSource.mRepeatCount),
|
2016-04-29 21:12:10 +03:00
|
|
|
mPositionXCount(aSource.mPositionXCount),
|
|
|
|
mPositionYCount(aSource.mPositionYCount),
|
2009-02-20 08:29:21 +03:00
|
|
|
mImageCount(aSource.mImageCount),
|
2009-05-28 22:09:05 +04:00
|
|
|
mSizeCount(aSource.mSizeCount),
|
2016-01-28 08:28:00 +03:00
|
|
|
mMaskModeCount(aSource.mMaskModeCount),
|
2013-11-08 19:07:36 +04:00
|
|
|
mBlendModeCount(aSource.mBlendModeCount),
|
2016-01-28 08:28:00 +03:00
|
|
|
mCompositeCount(aSource.mCompositeCount),
|
2009-02-20 08:29:21 +03:00
|
|
|
mLayers(aSource.mLayers) // deep copy
|
|
|
|
{
|
2016-01-28 08:24:00 +03:00
|
|
|
MOZ_COUNT_CTOR(nsStyleImageLayers);
|
2009-02-20 08:29:21 +03:00
|
|
|
// If the deep copy of mLayers failed, truncate the counts.
|
2012-08-22 19:56:38 +04:00
|
|
|
uint32_t count = mLayers.Length();
|
2009-02-20 08:29:21 +03:00
|
|
|
if (count != aSource.mLayers.Length()) {
|
|
|
|
NS_WARNING("truncating counts due to out-of-memory");
|
2013-01-15 16:22:03 +04:00
|
|
|
mAttachmentCount = std::max(mAttachmentCount, count);
|
|
|
|
mClipCount = std::max(mClipCount, count);
|
|
|
|
mOriginCount = std::max(mOriginCount, count);
|
|
|
|
mRepeatCount = std::max(mRepeatCount, count);
|
2016-04-29 21:12:10 +03:00
|
|
|
mPositionXCount = std::max(mPositionXCount, count);
|
|
|
|
mPositionYCount = std::max(mPositionYCount, count);
|
2013-01-15 16:22:03 +04:00
|
|
|
mImageCount = std::max(mImageCount, count);
|
|
|
|
mSizeCount = std::max(mSizeCount, count);
|
2016-01-28 08:28:00 +03:00
|
|
|
mMaskModeCount = std::max(mMaskModeCount, count);
|
2016-01-28 08:24:00 +03:00
|
|
|
mBlendModeCount = std::max(mBlendModeCount, count);
|
2016-01-28 08:28:00 +03:00
|
|
|
mCompositeCount = std::max(mCompositeCount, count);
|
2009-02-20 08:29:21 +03:00
|
|
|
}
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
|
|
|
|
2019-05-17 05:37:24 +03:00
|
|
|
static bool IsElementImage(const nsStyleImageLayers::Layer& aLayer) {
|
|
|
|
return aLayer.mImage.GetType() == eStyleImageType_Element;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool AnyLayerIsElementImage(const nsStyleImageLayers& aLayers) {
|
|
|
|
NS_FOR_VISIBLE_IMAGE_LAYERS_BACK_TO_FRONT(i, aLayers) {
|
|
|
|
if (IsElementImage(aLayers.mLayers[i])) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
nsChangeHint nsStyleImageLayers::CalcDifference(
|
2019-05-17 05:37:24 +03:00
|
|
|
const nsStyleImageLayers& aNewLayers, LayerType aType) const {
|
2016-01-28 08:28:00 +03:00
|
|
|
nsChangeHint hint = nsChangeHint(0);
|
|
|
|
|
2019-05-17 05:37:24 +03:00
|
|
|
// If the number of visible images changes, then it's easy-peasy.
|
|
|
|
if (mImageCount != aNewLayers.mImageCount) {
|
|
|
|
hint |= nsChangeHint_RepaintFrame;
|
|
|
|
if (aType == nsStyleImageLayers::LayerType::Mask ||
|
|
|
|
AnyLayerIsElementImage(*this) || AnyLayerIsElementImage(aNewLayers)) {
|
|
|
|
hint |= nsChangeHint_UpdateEffects;
|
|
|
|
}
|
|
|
|
return hint;
|
|
|
|
}
|
|
|
|
|
2016-01-28 08:28:00 +03:00
|
|
|
const nsStyleImageLayers& moreLayers =
|
2019-05-17 05:37:24 +03:00
|
|
|
mLayers.Length() > aNewLayers.mLayers.Length() ? *this : aNewLayers;
|
2016-01-28 08:28:00 +03:00
|
|
|
const nsStyleImageLayers& lessLayers =
|
2019-05-17 05:37:24 +03:00
|
|
|
mLayers.Length() > aNewLayers.mLayers.Length() ? aNewLayers : *this;
|
2016-01-28 08:28:00 +03:00
|
|
|
|
2019-05-17 05:37:24 +03:00
|
|
|
for (size_t i = 0; i < moreLayers.mLayers.Length(); ++i) {
|
|
|
|
const Layer& moreLayersLayer = moreLayers.mLayers[i];
|
|
|
|
if (i < moreLayers.mImageCount) {
|
|
|
|
// This is a visible image we're diffing, we may need to repaint.
|
|
|
|
const Layer& lessLayersLayer = lessLayers.mLayers[i];
|
2016-01-28 08:28:00 +03:00
|
|
|
nsChangeHint layerDifference =
|
2019-05-17 05:37:24 +03:00
|
|
|
moreLayersLayer.CalcDifference(lessLayersLayer);
|
|
|
|
if (layerDifference && (IsElementImage(moreLayersLayer) ||
|
|
|
|
IsElementImage(lessLayersLayer))) {
|
2019-05-22 00:07:55 +03:00
|
|
|
layerDifference |=
|
|
|
|
nsChangeHint_UpdateEffects | nsChangeHint_RepaintFrame;
|
2016-01-28 08:28:00 +03:00
|
|
|
}
|
2019-05-17 05:37:24 +03:00
|
|
|
hint |= layerDifference;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (hint) {
|
|
|
|
// If they're different by now, we're done.
|
|
|
|
return hint;
|
|
|
|
}
|
|
|
|
if (i >= lessLayers.mLayers.Length()) {
|
|
|
|
// The layer count differs, we know some property has changed, but if we
|
|
|
|
// got here we know it won't affect rendering.
|
|
|
|
return nsChangeHint_NeutralChange;
|
2016-01-28 08:28:00 +03:00
|
|
|
}
|
|
|
|
|
2019-05-17 05:37:24 +03:00
|
|
|
const Layer& lessLayersLayer = lessLayers.mLayers[i];
|
|
|
|
MOZ_ASSERT(moreLayersLayer.mImage.GetType() == eStyleImageType_Null);
|
|
|
|
MOZ_ASSERT(lessLayersLayer.mImage.GetType() == eStyleImageType_Null);
|
|
|
|
if (moreLayersLayer.CalcDifference(lessLayersLayer)) {
|
|
|
|
// We don't care about the difference returned, we know it's not visible,
|
|
|
|
// but if something changed, then we need to return the neutral change.
|
|
|
|
return nsChangeHint_NeutralChange;
|
|
|
|
}
|
2016-09-22 13:24:52 +03:00
|
|
|
}
|
|
|
|
|
2016-01-28 08:28:00 +03:00
|
|
|
if (hint) {
|
2019-05-17 05:37:24 +03:00
|
|
|
// If they're different by now, we're done.
|
2016-01-28 08:28:00 +03:00
|
|
|
return hint;
|
|
|
|
}
|
|
|
|
|
2019-05-17 05:37:24 +03:00
|
|
|
// We could have same layers and values, but different count still.
|
2016-06-21 04:47:54 +03:00
|
|
|
if (mAttachmentCount != aNewLayers.mAttachmentCount ||
|
|
|
|
mBlendModeCount != aNewLayers.mBlendModeCount ||
|
|
|
|
mClipCount != aNewLayers.mClipCount ||
|
|
|
|
mCompositeCount != aNewLayers.mCompositeCount ||
|
|
|
|
mMaskModeCount != aNewLayers.mMaskModeCount ||
|
|
|
|
mOriginCount != aNewLayers.mOriginCount ||
|
|
|
|
mRepeatCount != aNewLayers.mRepeatCount ||
|
|
|
|
mPositionXCount != aNewLayers.mPositionXCount ||
|
|
|
|
mPositionYCount != aNewLayers.mPositionYCount ||
|
|
|
|
mSizeCount != aNewLayers.mSizeCount) {
|
2016-05-23 06:26:03 +03:00
|
|
|
hint |= nsChangeHint_NeutralChange;
|
2016-01-28 08:28:00 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
return hint;
|
|
|
|
}
|
|
|
|
|
2016-11-07 17:32:15 +03:00
|
|
|
nsStyleImageLayers& nsStyleImageLayers::operator=(
|
|
|
|
const nsStyleImageLayers& aOther) {
|
|
|
|
mAttachmentCount = aOther.mAttachmentCount;
|
|
|
|
mClipCount = aOther.mClipCount;
|
|
|
|
mOriginCount = aOther.mOriginCount;
|
|
|
|
mRepeatCount = aOther.mRepeatCount;
|
|
|
|
mPositionXCount = aOther.mPositionXCount;
|
|
|
|
mPositionYCount = aOther.mPositionYCount;
|
|
|
|
mImageCount = aOther.mImageCount;
|
|
|
|
mSizeCount = aOther.mSizeCount;
|
|
|
|
mMaskModeCount = aOther.mMaskModeCount;
|
|
|
|
mBlendModeCount = aOther.mBlendModeCount;
|
|
|
|
mCompositeCount = aOther.mCompositeCount;
|
|
|
|
mLayers = aOther.mLayers;
|
|
|
|
|
|
|
|
uint32_t count = mLayers.Length();
|
|
|
|
if (count != aOther.mLayers.Length()) {
|
|
|
|
NS_WARNING("truncating counts due to out-of-memory");
|
|
|
|
mAttachmentCount = std::max(mAttachmentCount, count);
|
|
|
|
mClipCount = std::max(mClipCount, count);
|
|
|
|
mOriginCount = std::max(mOriginCount, count);
|
|
|
|
mRepeatCount = std::max(mRepeatCount, count);
|
|
|
|
mPositionXCount = std::max(mPositionXCount, count);
|
|
|
|
mPositionYCount = std::max(mPositionYCount, count);
|
|
|
|
mImageCount = std::max(mImageCount, count);
|
|
|
|
mSizeCount = std::max(mSizeCount, count);
|
|
|
|
mMaskModeCount = std::max(mMaskModeCount, count);
|
|
|
|
mBlendModeCount = std::max(mBlendModeCount, count);
|
|
|
|
mCompositeCount = std::max(mCompositeCount, count);
|
|
|
|
}
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2017-01-06 12:53:30 +03:00
|
|
|
nsStyleImageLayers& nsStyleImageLayers::operator=(nsStyleImageLayers&& aOther) {
|
|
|
|
mAttachmentCount = aOther.mAttachmentCount;
|
|
|
|
mClipCount = aOther.mClipCount;
|
|
|
|
mOriginCount = aOther.mOriginCount;
|
|
|
|
mRepeatCount = aOther.mRepeatCount;
|
|
|
|
mPositionXCount = aOther.mPositionXCount;
|
|
|
|
mPositionYCount = aOther.mPositionYCount;
|
|
|
|
mImageCount = aOther.mImageCount;
|
|
|
|
mSizeCount = aOther.mSizeCount;
|
|
|
|
mMaskModeCount = aOther.mMaskModeCount;
|
|
|
|
mBlendModeCount = aOther.mBlendModeCount;
|
|
|
|
mCompositeCount = aOther.mCompositeCount;
|
2018-05-30 22:15:35 +03:00
|
|
|
mLayers = std::move(aOther.mLayers);
|
2017-01-06 12:53:30 +03:00
|
|
|
|
|
|
|
uint32_t count = mLayers.Length();
|
|
|
|
if (count != aOther.mLayers.Length()) {
|
|
|
|
NS_WARNING("truncating counts due to out-of-memory");
|
|
|
|
mAttachmentCount = std::max(mAttachmentCount, count);
|
|
|
|
mClipCount = std::max(mClipCount, count);
|
|
|
|
mOriginCount = std::max(mOriginCount, count);
|
|
|
|
mRepeatCount = std::max(mRepeatCount, count);
|
|
|
|
mPositionXCount = std::max(mPositionXCount, count);
|
|
|
|
mPositionYCount = std::max(mPositionYCount, count);
|
|
|
|
mImageCount = std::max(mImageCount, count);
|
|
|
|
mSizeCount = std::max(mSizeCount, count);
|
|
|
|
mMaskModeCount = std::max(mMaskModeCount, count);
|
|
|
|
mBlendModeCount = std::max(mBlendModeCount, count);
|
|
|
|
mCompositeCount = std::max(mCompositeCount, count);
|
|
|
|
}
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool nsStyleImageLayers::operator==(const nsStyleImageLayers& aOther) const {
|
|
|
|
if (mAttachmentCount != aOther.mAttachmentCount ||
|
|
|
|
mClipCount != aOther.mClipCount || mOriginCount != aOther.mOriginCount ||
|
|
|
|
mRepeatCount != aOther.mRepeatCount ||
|
|
|
|
mPositionXCount != aOther.mPositionXCount ||
|
|
|
|
mPositionYCount != aOther.mPositionYCount ||
|
|
|
|
mImageCount != aOther.mImageCount || mSizeCount != aOther.mSizeCount ||
|
|
|
|
mMaskModeCount != aOther.mMaskModeCount ||
|
|
|
|
mBlendModeCount != aOther.mBlendModeCount) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mLayers.Length() != aOther.mLayers.Length()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < mLayers.Length(); i++) {
|
|
|
|
if (mLayers[i].mPosition != aOther.mLayers[i].mPosition ||
|
|
|
|
mLayers[i].mImage != aOther.mLayers[i].mImage ||
|
|
|
|
mLayers[i].mSize != aOther.mLayers[i].mSize ||
|
|
|
|
mLayers[i].mClip != aOther.mLayers[i].mClip ||
|
|
|
|
mLayers[i].mOrigin != aOther.mLayers[i].mOrigin ||
|
|
|
|
mLayers[i].mAttachment != aOther.mLayers[i].mAttachment ||
|
|
|
|
mLayers[i].mBlendMode != aOther.mLayers[i].mBlendMode ||
|
|
|
|
mLayers[i].mComposite != aOther.mLayers[i].mComposite ||
|
|
|
|
mLayers[i].mMaskMode != aOther.mLayers[i].mMaskMode ||
|
|
|
|
mLayers[i].mRepeat != aOther.mLayers[i].mRepeat) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-08-25 12:59:51 +03:00
|
|
|
bool nsStyleImageLayers::IsInitialPositionForLayerType(Position aPosition,
|
|
|
|
LayerType aType) {
|
2019-02-12 23:45:29 +03:00
|
|
|
return aPosition == Position::FromPercentage(0.);
|
2016-01-28 08:28:00 +03:00
|
|
|
}
|
|
|
|
|
2019-02-13 05:59:09 +03:00
|
|
|
static bool SizeDependsOnPositioningAreaSize(const StyleBackgroundSize& aSize,
|
|
|
|
const nsStyleImage& aImage) {
|
2015-02-10 01:34:50 +03:00
|
|
|
MOZ_ASSERT(aImage.GetType() != eStyleImageType_Null,
|
|
|
|
"caller should have handled this");
|
2011-01-13 13:40:12 +03:00
|
|
|
|
2019-02-13 05:59:09 +03:00
|
|
|
// Contain and cover straightforwardly depend on frame size.
|
|
|
|
if (aSize.IsCover() || aSize.IsContain()) {
|
2011-01-13 13:40:12 +03:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2019-02-13 05:59:09 +03:00
|
|
|
MOZ_ASSERT(aSize.IsExplicitSize());
|
|
|
|
auto& size = aSize.explicit_size;
|
|
|
|
|
|
|
|
// If either dimension contains a non-zero percentage, rendering for that
|
|
|
|
// dimension straightforwardly depends on frame size.
|
|
|
|
if (size.width.HasPercent() || size.height.HasPercent()) {
|
2011-01-13 13:40:12 +03:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If both dimensions are fixed lengths, there's no dependency.
|
2019-02-13 05:59:09 +03:00
|
|
|
if (!size.width.IsAuto() && !size.height.IsAuto()) {
|
2011-01-13 13:40:12 +03:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsStyleImageType type = aImage.GetType();
|
|
|
|
|
|
|
|
// Gradient rendering depends on frame size when auto is involved because
|
|
|
|
// gradients have no intrinsic ratio or dimensions, and therefore the relevant
|
|
|
|
// dimension is "treat[ed] as 100%".
|
|
|
|
if (type == eStyleImageType_Gradient) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// XXX Element rendering for auto or fixed length doesn't depend on frame size
|
|
|
|
// according to the spec. However, we don't implement the spec yet, so
|
|
|
|
// for now we bail and say element() plus auto affects ultimate size.
|
|
|
|
if (type == eStyleImageType_Element) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (type == eStyleImageType_Image) {
|
|
|
|
nsCOMPtr<imgIContainer> imgContainer;
|
2016-11-02 11:58:32 +03:00
|
|
|
if (imgRequestProxy* req = aImage.GetImageData()) {
|
|
|
|
req->GetImage(getter_AddRefs(imgContainer));
|
|
|
|
}
|
2011-01-13 13:40:12 +03:00
|
|
|
if (imgContainer) {
|
2015-03-30 18:35:47 +03:00
|
|
|
CSSIntSize imageSize;
|
2019-05-03 02:28:21 +03:00
|
|
|
AspectRatio imageRatio;
|
2011-01-13 13:40:12 +03:00
|
|
|
bool hasWidth, hasHeight;
|
|
|
|
nsLayoutUtils::ComputeSizeForDrawing(imgContainer, imageSize, imageRatio,
|
|
|
|
hasWidth, hasHeight);
|
|
|
|
|
|
|
|
// If the image has a fixed width and height, rendering never depends on
|
|
|
|
// the frame size.
|
|
|
|
if (hasWidth && hasHeight) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If the image has an intrinsic ratio, rendering will depend on frame
|
|
|
|
// size when background-size is all auto.
|
2019-05-03 02:28:21 +03:00
|
|
|
if (imageRatio) {
|
2019-02-13 05:59:09 +03:00
|
|
|
return size.width.IsAuto() == size.height.IsAuto();
|
2011-01-13 13:40:12 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// Otherwise, rendering depends on frame size when the image dimensions
|
|
|
|
// and background-size don't complement each other.
|
2019-02-13 05:59:09 +03:00
|
|
|
return !(hasWidth && size.width.IsLengthPercentage()) &&
|
|
|
|
!(hasHeight && size.height.IsLengthPercentage());
|
2011-01-13 13:40:12 +03:00
|
|
|
}
|
|
|
|
} else {
|
2018-06-18 08:43:11 +03:00
|
|
|
MOZ_ASSERT_UNREACHABLE("missed an enum value");
|
2011-01-13 13:40:12 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// Passed the gauntlet: no dependency.
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-01-28 08:24:00 +03:00
|
|
|
nsStyleImageLayers::Layer::Layer()
|
2019-02-13 05:59:09 +03:00
|
|
|
: mSize(StyleBackgroundSize::ExplicitSize(LengthPercentageOrAuto::Auto(),
|
|
|
|
LengthPercentageOrAuto::Auto())),
|
|
|
|
mClip(StyleGeometryBox::BorderBox),
|
2018-05-09 01:05:33 +03:00
|
|
|
mAttachment(StyleImageLayerAttachment::Scroll),
|
2016-06-03 18:56:54 +03:00
|
|
|
mBlendMode(NS_STYLE_BLEND_NORMAL),
|
|
|
|
mComposite(NS_STYLE_MASK_COMPOSITE_ADD),
|
2019-02-19 19:54:52 +03:00
|
|
|
mMaskMode(StyleMaskMode::MatchSource) {
|
2016-01-28 08:24:00 +03:00
|
|
|
mImage.SetNull();
|
2009-02-20 08:29:21 +03:00
|
|
|
}
|
|
|
|
|
2016-01-28 08:24:00 +03:00
|
|
|
nsStyleImageLayers::Layer::~Layer() {}
|
2009-02-20 08:29:21 +03:00
|
|
|
|
2016-06-03 18:56:54 +03:00
|
|
|
void nsStyleImageLayers::Layer::Initialize(
|
|
|
|
nsStyleImageLayers::LayerType aType) {
|
2016-10-13 17:57:10 +03:00
|
|
|
mRepeat.SetInitialValues();
|
2016-06-03 18:56:54 +03:00
|
|
|
|
2019-02-12 23:45:29 +03:00
|
|
|
mPosition = Position::FromPercentage(0.);
|
2016-08-15 10:33:03 +03:00
|
|
|
|
2016-06-03 18:56:54 +03:00
|
|
|
if (aType == LayerType::Background) {
|
2017-03-16 10:18:10 +03:00
|
|
|
mOrigin = StyleGeometryBox::PaddingBox;
|
2016-06-03 18:56:54 +03:00
|
|
|
} else {
|
|
|
|
MOZ_ASSERT(aType == LayerType::Mask, "unsupported layer type.");
|
2017-03-16 10:18:10 +03:00
|
|
|
mOrigin = StyleGeometryBox::BorderBox;
|
2016-06-03 18:56:54 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-28 08:24:00 +03:00
|
|
|
bool nsStyleImageLayers::Layer::
|
|
|
|
RenderingMightDependOnPositioningAreaSizeChange() const {
|
2010-10-07 02:18:52 +04:00
|
|
|
// Do we even have an image?
|
|
|
|
if (mImage.IsEmpty()) {
|
2011-10-17 18:59:28 +04:00
|
|
|
return false;
|
2010-10-07 02:18:52 +04:00
|
|
|
}
|
|
|
|
|
2012-11-08 19:05:32 +04:00
|
|
|
return mPosition.DependsOnPositioningAreaSize() ||
|
2019-02-13 05:59:09 +03:00
|
|
|
SizeDependsOnPositioningAreaSize(mSize, mImage) ||
|
2016-06-02 03:09:00 +03:00
|
|
|
mRepeat.DependsOnPositioningAreaSize();
|
2010-10-07 02:18:52 +04:00
|
|
|
}
|
|
|
|
|
2016-01-28 08:24:00 +03:00
|
|
|
bool nsStyleImageLayers::Layer::operator==(const Layer& aOther) const {
|
2009-02-20 08:29:21 +03:00
|
|
|
return mAttachment == aOther.mAttachment && mClip == aOther.mClip &&
|
|
|
|
mOrigin == aOther.mOrigin && mRepeat == aOther.mRepeat &&
|
2013-11-08 19:07:36 +04:00
|
|
|
mBlendMode == aOther.mBlendMode && mPosition == aOther.mPosition &&
|
2016-01-28 08:28:00 +03:00
|
|
|
mSize == aOther.mSize && mImage == aOther.mImage &&
|
|
|
|
mMaskMode == aOther.mMaskMode && mComposite == aOther.mComposite;
|
2009-08-01 19:53:40 +04:00
|
|
|
}
|
|
|
|
|
2017-11-20 08:53:58 +03:00
|
|
|
template <class ComputedValueItem>
|
|
|
|
static void FillImageLayerList(
|
|
|
|
nsStyleAutoArray<nsStyleImageLayers::Layer>& aLayers,
|
|
|
|
ComputedValueItem nsStyleImageLayers::Layer::*aResultLocation,
|
|
|
|
uint32_t aItemCount, uint32_t aFillCount) {
|
2018-04-28 22:50:58 +03:00
|
|
|
MOZ_ASSERT(aFillCount <= aLayers.Length(), "unexpected array length");
|
2017-11-20 08:53:58 +03:00
|
|
|
for (uint32_t sourceLayer = 0, destLayer = aItemCount; destLayer < aFillCount;
|
|
|
|
++sourceLayer, ++destLayer) {
|
|
|
|
aLayers[destLayer].*aResultLocation = aLayers[sourceLayer].*aResultLocation;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// The same as FillImageLayerList, but for values stored in
|
|
|
|
// layer.mPosition.*aResultLocation instead of layer.*aResultLocation.
|
|
|
|
static void FillImageLayerPositionCoordList(
|
|
|
|
nsStyleAutoArray<nsStyleImageLayers::Layer>& aLayers,
|
2019-02-12 23:45:29 +03:00
|
|
|
LengthPercentage Position::*aResultLocation, uint32_t aItemCount,
|
2017-11-20 08:53:58 +03:00
|
|
|
uint32_t aFillCount) {
|
2018-04-28 22:50:58 +03:00
|
|
|
MOZ_ASSERT(aFillCount <= aLayers.Length(), "unexpected array length");
|
2017-11-20 08:53:58 +03:00
|
|
|
for (uint32_t sourceLayer = 0, destLayer = aItemCount; destLayer < aFillCount;
|
|
|
|
++sourceLayer, ++destLayer) {
|
|
|
|
aLayers[destLayer].mPosition.*aResultLocation =
|
|
|
|
aLayers[sourceLayer].mPosition.*aResultLocation;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void nsStyleImageLayers::FillAllLayers(uint32_t aMaxItemCount) {
|
|
|
|
// Delete any extra items. We need to keep layers in which any
|
|
|
|
// property was specified.
|
|
|
|
mLayers.TruncateLengthNonZero(aMaxItemCount);
|
|
|
|
|
|
|
|
uint32_t fillCount = mImageCount;
|
|
|
|
FillImageLayerList(mLayers, &Layer::mImage, mImageCount, fillCount);
|
|
|
|
FillImageLayerList(mLayers, &Layer::mRepeat, mRepeatCount, fillCount);
|
|
|
|
FillImageLayerList(mLayers, &Layer::mAttachment, mAttachmentCount, fillCount);
|
|
|
|
FillImageLayerList(mLayers, &Layer::mClip, mClipCount, fillCount);
|
|
|
|
FillImageLayerList(mLayers, &Layer::mBlendMode, mBlendModeCount, fillCount);
|
|
|
|
FillImageLayerList(mLayers, &Layer::mOrigin, mOriginCount, fillCount);
|
2019-02-12 23:45:29 +03:00
|
|
|
FillImageLayerPositionCoordList(mLayers, &Position::horizontal,
|
2017-11-20 08:53:58 +03:00
|
|
|
mPositionXCount, fillCount);
|
2019-02-12 23:45:29 +03:00
|
|
|
FillImageLayerPositionCoordList(mLayers, &Position::vertical, mPositionYCount,
|
|
|
|
fillCount);
|
2017-11-20 08:53:58 +03:00
|
|
|
FillImageLayerList(mLayers, &Layer::mSize, mSizeCount, fillCount);
|
|
|
|
FillImageLayerList(mLayers, &Layer::mMaskMode, mMaskModeCount, fillCount);
|
|
|
|
FillImageLayerList(mLayers, &Layer::mComposite, mCompositeCount, fillCount);
|
|
|
|
}
|
2018-11-30 13:46:48 +03:00
|
|
|
|
Bug 1552708 - Use cbindgen for URIs. r=heycam
This doesn't clean up as much as a whole, but it's a step in the right
direction. In particular, it allows us to start using simple bindings for:
* Filters
* Shapes and images, almost. Need to:
* Get rid of the complex -moz- gradient parsing (let
layout.css.simple-moz-gradient.enabled get to release).
* Counters, almost. Need to:
* Share the Attr representation with Gecko, by not using Option<>.
* Just another variant should be enough (ContentItem::{Attr,Prefixedattr},
maybe).
Which in turn allows us to remove a whole lot of bindings in followups to this.
The setup changes a bit. This also removes the double pointer I complained about
while reviewing the shared UA sheet patches. The old setup is:
```
SpecifiedUrl
* CssUrl
* Arc<CssUrlData>
* String
* UrlExtraData
* UrlValueSource
* Arc<CssUrlData>
* load id
* resolved uri
* CORS mode.
* ...
```
The new one removes the double reference to the url data via URLValue, and looks
like:
```
SpecifiedUrl
* CssUrl
* Arc<CssUrlData>
* String
* UrlExtraData
* CorsMode
* LoadData
* load id
* resolved URI
```
The LoadData is the only mutable bit that C++ can change, and is not used from
Rust. Ideally, in the future, we could just use rust-url to resolve the URL
after parsing or something, and make it all immutable. Maybe.
I've verified that this approach still works with the UA sheet patches (via the
LoadDataSource::Lazy).
The reordering of mWillChange is to avoid nsStyleDisplay from going over the
size limit. We want to split it up anyway in bug 1552587, but mBinding gains a
tag member, which means that we were having a bit of extra padding.
One thing I want to explore is to see if we can abuse rustc's non-zero
optimizations to predict the layout from C++, but that's something to explore at
some other point in time and with a lot of care and help from Michael (who sits
next to me and works on rustc ;)).
Differential Revision: https://phabricator.services.mozilla.com/D31742
2019-05-27 14:45:12 +03:00
|
|
|
static bool UrlValuesEqual(const nsStyleImage& aImage,
|
|
|
|
const nsStyleImage& aOtherImage) {
|
|
|
|
auto* url = aImage.GetURLValue();
|
|
|
|
auto* other = aOtherImage.GetURLValue();
|
|
|
|
return url == other || (url && other && *url == *other);
|
|
|
|
}
|
|
|
|
|
2016-10-13 13:35:35 +03:00
|
|
|
nsChangeHint nsStyleImageLayers::Layer::CalcDifference(
|
|
|
|
const nsStyleImageLayers::Layer& aNewLayer) const {
|
2015-11-02 19:36:35 +03:00
|
|
|
nsChangeHint hint = nsChangeHint(0);
|
Bug 1552708 - Use cbindgen for URIs. r=heycam
This doesn't clean up as much as a whole, but it's a step in the right
direction. In particular, it allows us to start using simple bindings for:
* Filters
* Shapes and images, almost. Need to:
* Get rid of the complex -moz- gradient parsing (let
layout.css.simple-moz-gradient.enabled get to release).
* Counters, almost. Need to:
* Share the Attr representation with Gecko, by not using Option<>.
* Just another variant should be enough (ContentItem::{Attr,Prefixedattr},
maybe).
Which in turn allows us to remove a whole lot of bindings in followups to this.
The setup changes a bit. This also removes the double pointer I complained about
while reviewing the shared UA sheet patches. The old setup is:
```
SpecifiedUrl
* CssUrl
* Arc<CssUrlData>
* String
* UrlExtraData
* UrlValueSource
* Arc<CssUrlData>
* load id
* resolved uri
* CORS mode.
* ...
```
The new one removes the double reference to the url data via URLValue, and looks
like:
```
SpecifiedUrl
* CssUrl
* Arc<CssUrlData>
* String
* UrlExtraData
* CorsMode
* LoadData
* load id
* resolved URI
```
The LoadData is the only mutable bit that C++ can change, and is not used from
Rust. Ideally, in the future, we could just use rust-url to resolve the URL
after parsing or something, and make it all immutable. Maybe.
I've verified that this approach still works with the UA sheet patches (via the
LoadDataSource::Lazy).
The reordering of mWillChange is to avoid nsStyleDisplay from going over the
size limit. We want to split it up anyway in bug 1552587, but mBinding gains a
tag member, which means that we were having a bit of extra padding.
One thing I want to explore is to see if we can abuse rustc's non-zero
optimizations to predict the layout from C++, but that's something to explore at
some other point in time and with a lot of care and help from Michael (who sits
next to me and works on rustc ;)).
Differential Revision: https://phabricator.services.mozilla.com/D31742
2019-05-27 14:45:12 +03:00
|
|
|
if (!UrlValuesEqual(mImage, aNewLayer.mImage)) {
|
2016-09-22 13:24:52 +03:00
|
|
|
hint |= nsChangeHint_RepaintFrame | nsChangeHint_UpdateEffects;
|
2016-06-21 04:47:54 +03:00
|
|
|
} else if (mAttachment != aNewLayer.mAttachment || mClip != aNewLayer.mClip ||
|
|
|
|
mOrigin != aNewLayer.mOrigin || mRepeat != aNewLayer.mRepeat ||
|
|
|
|
mBlendMode != aNewLayer.mBlendMode || mSize != aNewLayer.mSize ||
|
|
|
|
mImage != aNewLayer.mImage || mMaskMode != aNewLayer.mMaskMode ||
|
|
|
|
mComposite != aNewLayer.mComposite) {
|
2015-11-02 19:36:35 +03:00
|
|
|
hint |= nsChangeHint_RepaintFrame;
|
|
|
|
}
|
2016-01-28 08:37:00 +03:00
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
if (mPosition != aNewLayer.mPosition) {
|
2016-10-13 13:35:35 +03:00
|
|
|
hint |= nsChangeHint_UpdateBackgroundPosition;
|
2015-11-02 19:36:35 +03:00
|
|
|
}
|
2016-01-28 08:37:00 +03:00
|
|
|
|
2015-11-02 19:36:35 +03:00
|
|
|
return hint;
|
|
|
|
}
|
|
|
|
|
2016-01-28 08:24:00 +03:00
|
|
|
// --------------------
|
|
|
|
// nsStyleBackground
|
|
|
|
//
|
|
|
|
|
2019-01-18 20:32:22 +03:00
|
|
|
nsStyleBackground::nsStyleBackground(const Document& aDocument)
|
2016-06-03 18:56:54 +03:00
|
|
|
: mImage(nsStyleImageLayers::LayerType::Background),
|
2019-04-04 14:35:33 +03:00
|
|
|
mBackgroundColor(StyleColor::Transparent()) {
|
2016-01-28 08:24:00 +03:00
|
|
|
MOZ_COUNT_CTOR(nsStyleBackground);
|
|
|
|
}
|
|
|
|
|
|
|
|
nsStyleBackground::nsStyleBackground(const nsStyleBackground& aSource)
|
|
|
|
: mImage(aSource.mImage), mBackgroundColor(aSource.mBackgroundColor) {
|
|
|
|
MOZ_COUNT_CTOR(nsStyleBackground);
|
|
|
|
}
|
|
|
|
|
|
|
|
nsStyleBackground::~nsStyleBackground() { MOZ_COUNT_DTOR(nsStyleBackground); }
|
|
|
|
|
2019-02-04 19:03:25 +03:00
|
|
|
void nsStyleBackground::TriggerImageLoads(Document& aDocument,
|
|
|
|
const nsStyleBackground* aOldStyle) {
|
2016-11-02 11:58:32 +03:00
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
2019-02-02 21:42:25 +03:00
|
|
|
mImage.ResolveImages(aDocument, aOldStyle ? &aOldStyle->mImage : nullptr);
|
2016-11-02 11:58:32 +03:00
|
|
|
}
|
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
nsChangeHint nsStyleBackground::CalcDifference(
|
|
|
|
const nsStyleBackground& aNewData) const {
|
2016-01-28 08:24:00 +03:00
|
|
|
nsChangeHint hint = nsChangeHint(0);
|
2016-06-21 04:47:54 +03:00
|
|
|
if (mBackgroundColor != aNewData.mBackgroundColor) {
|
2016-01-28 08:24:00 +03:00
|
|
|
hint |= nsChangeHint_RepaintFrame;
|
|
|
|
}
|
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
hint |= mImage.CalcDifference(aNewData.mImage,
|
2016-09-22 13:24:52 +03:00
|
|
|
nsStyleImageLayers::LayerType::Background);
|
2016-01-28 08:24:00 +03:00
|
|
|
|
2016-01-28 08:28:00 +03:00
|
|
|
return hint;
|
2016-01-28 08:24:00 +03:00
|
|
|
}
|
|
|
|
|
2016-06-03 18:56:54 +03:00
|
|
|
bool nsStyleBackground::HasFixedBackground(nsIFrame* aFrame) const {
|
2016-01-28 08:39:00 +03:00
|
|
|
NS_FOR_VISIBLE_IMAGE_LAYERS_BACK_TO_FRONT(i, mImage) {
|
|
|
|
const nsStyleImageLayers::Layer& layer = mImage.mLayers[i];
|
2018-05-09 01:05:33 +03:00
|
|
|
if (layer.mAttachment == StyleImageLayerAttachment::Fixed &&
|
2016-04-26 00:20:13 +03:00
|
|
|
!layer.mImage.IsEmpty() && !nsLayoutUtils::IsTransformed(aFrame)) {
|
2016-01-28 08:24:00 +03:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-12-29 18:03:29 +03:00
|
|
|
nscolor nsStyleBackground::BackgroundColor(const nsIFrame* aFrame) const {
|
2018-04-27 05:07:20 +03:00
|
|
|
return mBackgroundColor.CalcColor(aFrame);
|
2016-12-29 18:03:29 +03:00
|
|
|
}
|
|
|
|
|
2019-04-04 14:35:16 +03:00
|
|
|
nscolor nsStyleBackground::BackgroundColor(ComputedStyle* aStyle) const {
|
|
|
|
return mBackgroundColor.CalcColor(*aStyle);
|
2016-12-29 18:03:29 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
bool nsStyleBackground::IsTransparent(const nsIFrame* aFrame) const {
|
2018-03-22 21:20:41 +03:00
|
|
|
return IsTransparent(aFrame->Style());
|
2016-12-29 18:03:29 +03:00
|
|
|
}
|
|
|
|
|
2018-03-22 21:20:41 +03:00
|
|
|
bool nsStyleBackground::IsTransparent(mozilla::ComputedStyle* aStyle) const {
|
2016-01-28 08:24:00 +03:00
|
|
|
return BottomLayer().mImage.IsEmpty() && mImage.mImageCount == 1 &&
|
2018-03-22 21:20:41 +03:00
|
|
|
NS_GET_A(BackgroundColor(aStyle)) == 0;
|
2016-01-28 08:24:00 +03:00
|
|
|
}
|
|
|
|
|
2016-07-25 09:22:34 +03:00
|
|
|
StyleTransition::StyleTransition(const StyleTransition& aCopy)
|
2009-08-21 01:52:47 +04:00
|
|
|
: mTimingFunction(aCopy.mTimingFunction),
|
|
|
|
mDuration(aCopy.mDuration),
|
|
|
|
mDelay(aCopy.mDelay),
|
|
|
|
mProperty(aCopy.mProperty),
|
2010-10-21 04:24:16 +04:00
|
|
|
mUnknownProperty(aCopy.mUnknownProperty) {}
|
2009-08-21 01:52:47 +04:00
|
|
|
|
2016-07-25 09:22:34 +03:00
|
|
|
void StyleTransition::SetInitialValues() {
|
2018-10-26 21:03:35 +03:00
|
|
|
mTimingFunction = nsTimingFunction(StyleTimingKeyword::Ease);
|
2009-08-21 01:52:47 +04:00
|
|
|
mDuration = 0.0;
|
|
|
|
mDelay = 0.0;
|
|
|
|
mProperty = eCSSPropertyExtra_all_properties;
|
|
|
|
}
|
|
|
|
|
2016-07-25 09:26:05 +03:00
|
|
|
bool StyleTransition::operator==(const StyleTransition& aOther) const {
|
2014-09-05 07:48:43 +04:00
|
|
|
return mTimingFunction == aOther.mTimingFunction &&
|
|
|
|
mDuration == aOther.mDuration && mDelay == aOther.mDelay &&
|
|
|
|
mProperty == aOther.mProperty &&
|
|
|
|
(mProperty != eCSSProperty_UNKNOWN ||
|
|
|
|
mUnknownProperty == aOther.mUnknownProperty);
|
|
|
|
}
|
|
|
|
|
2016-07-25 09:26:05 +03:00
|
|
|
StyleAnimation::StyleAnimation(const StyleAnimation& aCopy)
|
2011-04-12 10:18:42 +04:00
|
|
|
: mTimingFunction(aCopy.mTimingFunction),
|
|
|
|
mDuration(aCopy.mDuration),
|
|
|
|
mDelay(aCopy.mDelay),
|
|
|
|
mName(aCopy.mName),
|
|
|
|
mDirection(aCopy.mDirection),
|
|
|
|
mFillMode(aCopy.mFillMode),
|
|
|
|
mPlayState(aCopy.mPlayState),
|
|
|
|
mIterationCount(aCopy.mIterationCount) {}
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2016-07-25 09:22:34 +03:00
|
|
|
void StyleAnimation::SetInitialValues() {
|
2018-10-26 21:03:35 +03:00
|
|
|
mTimingFunction = nsTimingFunction(StyleTimingKeyword::Ease);
|
2011-04-12 10:18:42 +04:00
|
|
|
mDuration = 0.0;
|
|
|
|
mDelay = 0.0;
|
2017-10-10 11:00:28 +03:00
|
|
|
mName = nsGkAtoms::_empty;
|
2015-11-20 08:09:00 +03:00
|
|
|
mDirection = dom::PlaybackDirection::Normal;
|
|
|
|
mFillMode = dom::FillMode::None;
|
2018-10-23 00:58:01 +03:00
|
|
|
mPlayState = StyleAnimationPlayState::Running;
|
2011-04-12 10:18:42 +04:00
|
|
|
mIterationCount = 1.0f;
|
|
|
|
}
|
|
|
|
|
2016-07-25 09:26:05 +03:00
|
|
|
bool StyleAnimation::operator==(const StyleAnimation& aOther) const {
|
2014-09-05 07:48:43 +04:00
|
|
|
return mTimingFunction == aOther.mTimingFunction &&
|
|
|
|
mDuration == aOther.mDuration && mDelay == aOther.mDelay &&
|
|
|
|
mName == aOther.mName && mDirection == aOther.mDirection &&
|
|
|
|
mFillMode == aOther.mFillMode && mPlayState == aOther.mPlayState &&
|
|
|
|
mIterationCount == aOther.mIterationCount;
|
|
|
|
}
|
|
|
|
|
2016-05-03 12:26:29 +03:00
|
|
|
// --------------------
|
|
|
|
// nsStyleDisplay
|
|
|
|
//
|
2019-01-18 20:32:22 +03:00
|
|
|
nsStyleDisplay::nsStyleDisplay(const Document& aDocument)
|
Bug 1552708 - Use cbindgen for URIs. r=heycam
This doesn't clean up as much as a whole, but it's a step in the right
direction. In particular, it allows us to start using simple bindings for:
* Filters
* Shapes and images, almost. Need to:
* Get rid of the complex -moz- gradient parsing (let
layout.css.simple-moz-gradient.enabled get to release).
* Counters, almost. Need to:
* Share the Attr representation with Gecko, by not using Option<>.
* Just another variant should be enough (ContentItem::{Attr,Prefixedattr},
maybe).
Which in turn allows us to remove a whole lot of bindings in followups to this.
The setup changes a bit. This also removes the double pointer I complained about
while reviewing the shared UA sheet patches. The old setup is:
```
SpecifiedUrl
* CssUrl
* Arc<CssUrlData>
* String
* UrlExtraData
* UrlValueSource
* Arc<CssUrlData>
* load id
* resolved uri
* CORS mode.
* ...
```
The new one removes the double reference to the url data via URLValue, and looks
like:
```
SpecifiedUrl
* CssUrl
* Arc<CssUrlData>
* String
* UrlExtraData
* CorsMode
* LoadData
* load id
* resolved URI
```
The LoadData is the only mutable bit that C++ can change, and is not used from
Rust. Ideally, in the future, we could just use rust-url to resolve the URL
after parsing or something, and make it all immutable. Maybe.
I've verified that this approach still works with the UA sheet patches (via the
LoadDataSource::Lazy).
The reordering of mWillChange is to avoid nsStyleDisplay from going over the
size limit. We want to split it up anyway in bug 1552587, but mBinding gains a
tag member, which means that we were having a bit of extra padding.
One thing I want to explore is to see if we can abuse rustc's non-zero
optimizations to predict the layout from C++, but that's something to explore at
some other point in time and with a lot of care and help from Michael (who sits
next to me and works on rustc ;)).
Differential Revision: https://phabricator.services.mozilla.com/D31742
2019-05-27 14:45:12 +03:00
|
|
|
: mBinding(StyleUrlOrNone::None()),
|
|
|
|
mTransitions(
|
2019-05-21 02:42:40 +03:00
|
|
|
nsStyleAutoArray<StyleTransition>::WITH_SINGLE_INITIAL_ELEMENT),
|
|
|
|
mTransitionTimingFunctionCount(1),
|
|
|
|
mTransitionDurationCount(1),
|
|
|
|
mTransitionDelayCount(1),
|
|
|
|
mTransitionPropertyCount(1),
|
|
|
|
mAnimations(
|
|
|
|
nsStyleAutoArray<StyleAnimation>::WITH_SINGLE_INITIAL_ELEMENT),
|
|
|
|
mAnimationTimingFunctionCount(1),
|
|
|
|
mAnimationDurationCount(1),
|
|
|
|
mAnimationDelayCount(1),
|
|
|
|
mAnimationNameCount(1),
|
|
|
|
mAnimationDirectionCount(1),
|
|
|
|
mAnimationFillModeCount(1),
|
|
|
|
mAnimationPlayStateCount(1),
|
|
|
|
mAnimationIterationCountCount(1),
|
|
|
|
mWillChange{{}, {0}},
|
|
|
|
mDisplay(StyleDisplay::Inline),
|
2016-08-28 05:31:50 +03:00
|
|
|
mOriginalDisplay(StyleDisplay::Inline),
|
2019-03-13 22:55:54 +03:00
|
|
|
mContain(StyleContain_NONE),
|
2018-07-25 16:03:45 +03:00
|
|
|
mAppearance(StyleAppearance::None),
|
2016-05-03 12:26:29 +03:00
|
|
|
mPosition(NS_STYLE_POSITION_STATIC),
|
2016-09-03 21:46:58 +03:00
|
|
|
mFloat(StyleFloat::None),
|
|
|
|
mBreakType(StyleClear::None),
|
2018-11-15 11:16:23 +03:00
|
|
|
mBreakInside(StyleBreakWithin::Auto),
|
2018-11-30 08:35:47 +03:00
|
|
|
mBreakBefore(StyleBreakBetween::Auto),
|
|
|
|
mBreakAfter(StyleBreakBetween::Auto),
|
2018-12-11 03:50:32 +03:00
|
|
|
mOverflowX(StyleOverflow::Visible),
|
|
|
|
mOverflowY(StyleOverflow::Visible),
|
2018-12-06 02:04:51 +03:00
|
|
|
mOverflowClipBoxBlock(StyleOverflowClipBox::PaddingBox),
|
|
|
|
mOverflowClipBoxInline(StyleOverflowClipBox::PaddingBox),
|
|
|
|
mResize(StyleResize::None),
|
2016-10-28 07:17:20 +03:00
|
|
|
mOrient(StyleOrient::Inline),
|
2016-05-03 12:26:29 +03:00
|
|
|
mIsolation(NS_STYLE_ISOLATION_AUTO),
|
|
|
|
mTopLayer(NS_STYLE_TOP_LAYER_NONE),
|
2019-03-18 21:01:55 +03:00
|
|
|
mTouchAction(StyleTouchAction_AUTO),
|
2016-05-03 12:26:29 +03:00
|
|
|
mScrollBehavior(NS_STYLE_SCROLL_BEHAVIOR_AUTO),
|
2017-11-23 03:01:11 +03:00
|
|
|
mOverscrollBehaviorX(StyleOverscrollBehavior::Auto),
|
|
|
|
mOverscrollBehaviorY(StyleOverscrollBehavior::Auto),
|
2018-11-22 07:33:15 +03:00
|
|
|
mOverflowAnchor(StyleOverflowAnchor::Auto),
|
2019-04-11 09:19:31 +03:00
|
|
|
mScrollSnapType(
|
|
|
|
{StyleScrollSnapAxis::Both, StyleScrollSnapStrictness::None}),
|
2019-05-21 02:42:40 +03:00
|
|
|
mLineClamp(0),
|
2016-05-03 12:26:29 +03:00
|
|
|
mBackfaceVisibility(NS_STYLE_BACKFACE_VISIBILITY_VISIBLE),
|
|
|
|
mTransformStyle(NS_STYLE_TRANSFORM_STYLE_FLAT),
|
2017-03-16 10:18:10 +03:00
|
|
|
mTransformBox(StyleGeometryBox::BorderBox),
|
2019-05-21 02:42:50 +03:00
|
|
|
mOffsetPath(StyleOffsetPath::None()),
|
2019-05-21 02:42:52 +03:00
|
|
|
mOffsetDistance(LengthPercentage::Zero()),
|
2019-05-24 06:42:03 +03:00
|
|
|
mOffsetRotate{true, StyleAngle{0.0}},
|
2019-02-19 23:28:47 +03:00
|
|
|
mTransformOrigin{LengthPercentage::FromPercentage(0.5),
|
|
|
|
LengthPercentage::FromPercentage(0.5),
|
|
|
|
{0.}},
|
2019-02-20 02:04:45 +03:00
|
|
|
mChildPerspective(StylePerspective::None()),
|
2019-02-19 23:28:47 +03:00
|
|
|
mPerspectiveOrigin(Position::FromPercentage(0.5f)),
|
2019-05-01 16:08:34 +03:00
|
|
|
mVerticalAlign(
|
|
|
|
StyleVerticalAlign::Keyword(StyleVerticalAlignKeyword::Baseline)),
|
2019-01-26 13:00:22 +03:00
|
|
|
mShapeMargin(LengthPercentage::Zero()) {
|
2009-08-07 18:38:44 +04:00
|
|
|
MOZ_COUNT_CTOR(nsStyleDisplay);
|
2016-05-03 12:26:30 +03:00
|
|
|
|
2009-08-21 01:52:47 +04:00
|
|
|
mTransitions[0].SetInitialValues();
|
2011-04-12 10:18:42 +04:00
|
|
|
mAnimations[0].SetInitialValues();
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
nsStyleDisplay::nsStyleDisplay(const nsStyleDisplay& aSource)
|
2012-07-07 03:31:54 +04:00
|
|
|
: mBinding(aSource.mBinding),
|
2019-05-21 02:42:40 +03:00
|
|
|
mTransitions(aSource.mTransitions),
|
|
|
|
mTransitionTimingFunctionCount(aSource.mTransitionTimingFunctionCount),
|
|
|
|
mTransitionDurationCount(aSource.mTransitionDurationCount),
|
|
|
|
mTransitionDelayCount(aSource.mTransitionDelayCount),
|
|
|
|
mTransitionPropertyCount(aSource.mTransitionPropertyCount),
|
|
|
|
mAnimations(aSource.mAnimations),
|
|
|
|
mAnimationTimingFunctionCount(aSource.mAnimationTimingFunctionCount),
|
|
|
|
mAnimationDurationCount(aSource.mAnimationDurationCount),
|
|
|
|
mAnimationDelayCount(aSource.mAnimationDelayCount),
|
|
|
|
mAnimationNameCount(aSource.mAnimationNameCount),
|
|
|
|
mAnimationDirectionCount(aSource.mAnimationDirectionCount),
|
|
|
|
mAnimationFillModeCount(aSource.mAnimationFillModeCount),
|
|
|
|
mAnimationPlayStateCount(aSource.mAnimationPlayStateCount),
|
|
|
|
mAnimationIterationCountCount(aSource.mAnimationIterationCountCount),
|
|
|
|
mWillChange(aSource.mWillChange),
|
2012-07-07 03:31:54 +04:00
|
|
|
mDisplay(aSource.mDisplay),
|
|
|
|
mOriginalDisplay(aSource.mOriginalDisplay),
|
2015-06-04 17:38:00 +03:00
|
|
|
mContain(aSource.mContain),
|
2012-07-07 03:31:54 +04:00
|
|
|
mAppearance(aSource.mAppearance),
|
|
|
|
mPosition(aSource.mPosition),
|
2016-06-19 00:16:20 +03:00
|
|
|
mFloat(aSource.mFloat),
|
2012-07-07 03:31:54 +04:00
|
|
|
mBreakType(aSource.mBreakType),
|
2012-11-08 20:09:37 +04:00
|
|
|
mBreakInside(aSource.mBreakInside),
|
2018-11-30 08:35:47 +03:00
|
|
|
mBreakBefore(aSource.mBreakBefore),
|
|
|
|
mBreakAfter(aSource.mBreakAfter),
|
2012-07-07 03:31:54 +04:00
|
|
|
mOverflowX(aSource.mOverflowX),
|
|
|
|
mOverflowY(aSource.mOverflowY),
|
2017-12-05 23:08:41 +03:00
|
|
|
mOverflowClipBoxBlock(aSource.mOverflowClipBoxBlock),
|
|
|
|
mOverflowClipBoxInline(aSource.mOverflowClipBoxInline),
|
2012-07-07 03:31:54 +04:00
|
|
|
mResize(aSource.mResize),
|
|
|
|
mOrient(aSource.mOrient),
|
2014-10-15 16:13:00 +04:00
|
|
|
mIsolation(aSource.mIsolation),
|
2015-10-07 06:04:32 +03:00
|
|
|
mTopLayer(aSource.mTopLayer),
|
2014-01-15 19:03:15 +04:00
|
|
|
mTouchAction(aSource.mTouchAction),
|
2014-09-15 23:29:58 +04:00
|
|
|
mScrollBehavior(aSource.mScrollBehavior),
|
2017-11-23 03:01:11 +03:00
|
|
|
mOverscrollBehaviorX(aSource.mOverscrollBehaviorX),
|
|
|
|
mOverscrollBehaviorY(aSource.mOverscrollBehaviorY),
|
2019-04-11 09:19:31 +03:00
|
|
|
mScrollSnapType(aSource.mScrollSnapType),
|
2019-05-21 02:42:40 +03:00
|
|
|
mLineClamp(aSource.mLineClamp),
|
2019-05-17 02:25:10 +03:00
|
|
|
mTransform(aSource.mTransform),
|
|
|
|
mRotate(aSource.mRotate),
|
|
|
|
mTranslate(aSource.mTranslate),
|
|
|
|
mScale(aSource.mScale),
|
2019-05-21 02:42:40 +03:00
|
|
|
mBackfaceVisibility(aSource.mBackfaceVisibility),
|
|
|
|
mTransformStyle(aSource.mTransformStyle),
|
|
|
|
mTransformBox(aSource.mTransformBox),
|
2019-05-21 02:42:50 +03:00
|
|
|
mOffsetPath(aSource.mOffsetPath),
|
2019-05-21 02:42:52 +03:00
|
|
|
mOffsetDistance(aSource.mOffsetDistance),
|
2019-05-24 06:42:03 +03:00
|
|
|
mOffsetRotate(aSource.mOffsetRotate),
|
2019-02-19 23:28:47 +03:00
|
|
|
mTransformOrigin(aSource.mTransformOrigin),
|
2015-03-20 07:12:17 +03:00
|
|
|
mChildPerspective(aSource.mChildPerspective),
|
2019-02-19 23:28:47 +03:00
|
|
|
mPerspectiveOrigin(aSource.mPerspectiveOrigin),
|
2016-04-12 08:52:41 +03:00
|
|
|
mVerticalAlign(aSource.mVerticalAlign),
|
2017-11-27 10:01:25 +03:00
|
|
|
mShapeImageThreshold(aSource.mShapeImageThreshold),
|
2018-02-08 04:27:04 +03:00
|
|
|
mShapeMargin(aSource.mShapeMargin),
|
2016-07-22 10:40:01 +03:00
|
|
|
mShapeOutside(aSource.mShapeOutside) {
|
2009-08-07 18:38:44 +04:00
|
|
|
MOZ_COUNT_CTOR(nsStyleDisplay);
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
|
|
|
|
2019-05-22 00:07:55 +03:00
|
|
|
nsStyleDisplay::~nsStyleDisplay() { MOZ_COUNT_DTOR(nsStyleDisplay); }
|
2017-02-08 06:25:45 +03:00
|
|
|
|
2019-02-04 19:03:25 +03:00
|
|
|
void nsStyleDisplay::TriggerImageLoads(Document& aDocument,
|
|
|
|
const nsStyleDisplay* aOldStyle) {
|
2017-11-17 11:34:37 +03:00
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
|
2019-02-04 19:03:25 +03:00
|
|
|
mShapeOutside.TriggerImageLoads(
|
|
|
|
aDocument, aOldStyle ? &aOldStyle->mShapeOutside : nullptr);
|
2017-11-17 11:34:37 +03:00
|
|
|
}
|
|
|
|
|
2019-05-17 02:25:10 +03:00
|
|
|
template <typename TransformLike>
|
2017-12-06 12:17:34 +03:00
|
|
|
static inline nsChangeHint CompareTransformValues(
|
2019-05-17 02:25:10 +03:00
|
|
|
const TransformLike& aOldTransform, const TransformLike& aNewTransform) {
|
2017-12-06 12:17:34 +03:00
|
|
|
nsChangeHint result = nsChangeHint(0);
|
2018-06-25 12:29:28 +03:00
|
|
|
|
|
|
|
// Note: If we add a new change hint for transform changes here, we have to
|
|
|
|
// modify KeyframeEffect::CalculateCumulativeChangeHint too!
|
2019-05-17 02:25:10 +03:00
|
|
|
if (aOldTransform != aNewTransform) {
|
2017-12-06 12:17:34 +03:00
|
|
|
result |= nsChangeHint_UpdateTransformLayer;
|
2019-05-17 02:25:10 +03:00
|
|
|
if (!aOldTransform.IsNone() && !aNewTransform.IsNone()) {
|
2017-12-06 12:17:34 +03:00
|
|
|
result |= nsChangeHint_UpdatePostTransformOverflow;
|
|
|
|
} else {
|
|
|
|
result |= nsChangeHint_UpdateOverflow;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2019-05-21 02:42:50 +03:00
|
|
|
static inline nsChangeHint CompareMotionValues(
|
2019-05-24 06:42:03 +03:00
|
|
|
const nsStyleDisplay& aDisplay, const nsStyleDisplay& aNewDisplay) {
|
|
|
|
if (aDisplay.mOffsetPath == aNewDisplay.mOffsetPath) {
|
|
|
|
if (aDisplay.mOffsetDistance == aNewDisplay.mOffsetDistance &&
|
|
|
|
aDisplay.mOffsetRotate == aNewDisplay.mOffsetRotate) {
|
2019-05-21 02:42:52 +03:00
|
|
|
return nsChangeHint(0);
|
|
|
|
}
|
|
|
|
|
2019-05-24 06:42:03 +03:00
|
|
|
if (aDisplay.mOffsetPath.IsNone()) {
|
2019-05-21 02:42:52 +03:00
|
|
|
return nsChangeHint_NeutralChange;
|
|
|
|
}
|
2019-05-21 02:42:50 +03:00
|
|
|
}
|
|
|
|
|
2018-07-07 00:31:52 +03:00
|
|
|
// TODO: Bug 1482737: This probably doesn't need to UpdateOverflow
|
|
|
|
// (or UpdateTransformLayer) if there's already a transform.
|
2019-05-21 02:42:50 +03:00
|
|
|
// Set the same hints as what we use for transform because motion path is
|
|
|
|
// a kind of transform and will be combined with other transforms.
|
2019-05-21 02:42:52 +03:00
|
|
|
nsChangeHint result = nsChangeHint_UpdateTransformLayer;
|
2019-05-24 06:42:03 +03:00
|
|
|
if (!aDisplay.mOffsetPath.IsNone() && !aNewDisplay.mOffsetPath.IsNone()) {
|
2019-05-21 02:42:50 +03:00
|
|
|
result |= nsChangeHint_UpdatePostTransformOverflow;
|
|
|
|
} else {
|
|
|
|
result |= nsChangeHint_UpdateOverflow;
|
2018-07-07 00:31:52 +03:00
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
nsChangeHint nsStyleDisplay::CalcDifference(
|
2019-06-11 12:12:10 +03:00
|
|
|
const nsStyleDisplay& aNewData, const nsStylePosition& aOldPosition) const {
|
2003-07-12 01:16:12 +04:00
|
|
|
nsChangeHint hint = nsChangeHint(0);
|
2002-09-30 15:56:37 +04:00
|
|
|
|
Bug 1552708 - Use cbindgen for URIs. r=heycam
This doesn't clean up as much as a whole, but it's a step in the right
direction. In particular, it allows us to start using simple bindings for:
* Filters
* Shapes and images, almost. Need to:
* Get rid of the complex -moz- gradient parsing (let
layout.css.simple-moz-gradient.enabled get to release).
* Counters, almost. Need to:
* Share the Attr representation with Gecko, by not using Option<>.
* Just another variant should be enough (ContentItem::{Attr,Prefixedattr},
maybe).
Which in turn allows us to remove a whole lot of bindings in followups to this.
The setup changes a bit. This also removes the double pointer I complained about
while reviewing the shared UA sheet patches. The old setup is:
```
SpecifiedUrl
* CssUrl
* Arc<CssUrlData>
* String
* UrlExtraData
* UrlValueSource
* Arc<CssUrlData>
* load id
* resolved uri
* CORS mode.
* ...
```
The new one removes the double reference to the url data via URLValue, and looks
like:
```
SpecifiedUrl
* CssUrl
* Arc<CssUrlData>
* String
* UrlExtraData
* CorsMode
* LoadData
* load id
* resolved URI
```
The LoadData is the only mutable bit that C++ can change, and is not used from
Rust. Ideally, in the future, we could just use rust-url to resolve the URL
after parsing or something, and make it all immutable. Maybe.
I've verified that this approach still works with the UA sheet patches (via the
LoadDataSource::Lazy).
The reordering of mWillChange is to avoid nsStyleDisplay from going over the
size limit. We want to split it up anyway in bug 1552587, but mBinding gains a
tag member, which means that we were having a bit of extra padding.
One thing I want to explore is to see if we can abuse rustc's non-zero
optimizations to predict the layout from C++, but that's something to explore at
some other point in time and with a lot of care and help from Michael (who sits
next to me and works on rustc ;)).
Differential Revision: https://phabricator.services.mozilla.com/D31742
2019-05-27 14:45:12 +03:00
|
|
|
if (mBinding != aNewData.mBinding || mPosition != aNewData.mPosition ||
|
|
|
|
mDisplay != aNewData.mDisplay || mContain != aNewData.mContain ||
|
2016-09-03 21:46:58 +03:00
|
|
|
(mFloat == StyleFloat::None) != (aNewData.mFloat == StyleFloat::None) ||
|
2016-06-21 04:47:54 +03:00
|
|
|
mScrollBehavior != aNewData.mScrollBehavior ||
|
2019-04-11 09:19:31 +03:00
|
|
|
mScrollSnapType != aNewData.mScrollSnapType ||
|
2016-06-21 04:47:54 +03:00
|
|
|
mTopLayer != aNewData.mTopLayer || mResize != aNewData.mResize) {
|
2017-07-15 03:16:47 +03:00
|
|
|
return nsChangeHint_ReconstructFrame;
|
|
|
|
}
|
|
|
|
|
2018-07-25 16:03:45 +03:00
|
|
|
if ((mAppearance == StyleAppearance::Textfield &&
|
|
|
|
aNewData.mAppearance != StyleAppearance::Textfield) ||
|
|
|
|
(mAppearance != StyleAppearance::Textfield &&
|
|
|
|
aNewData.mAppearance == StyleAppearance::Textfield)) {
|
2018-02-05 23:39:07 +03:00
|
|
|
// This is for <input type=number> where we allow authors to specify a
|
|
|
|
// |-moz-appearance:textfield| to get a control without a spinner. (The
|
|
|
|
// spinner is present for |-moz-appearance:number-input| but also other
|
|
|
|
// values such as 'none'.) We need to reframe since we want to use
|
|
|
|
// nsTextControlFrame instead of nsNumberControlFrame if the author
|
|
|
|
// specifies 'textfield'.
|
2017-07-15 03:16:47 +03:00
|
|
|
return nsChangeHint_ReconstructFrame;
|
2016-07-06 08:06:13 +03:00
|
|
|
}
|
2002-09-30 15:56:37 +04:00
|
|
|
|
2019-04-11 09:20:36 +03:00
|
|
|
if (mScrollSnapAlign != aNewData.mScrollSnapAlign) {
|
|
|
|
// FIXME: Bug 1530253 Support re-snapping when scroll-snap-align changes.
|
|
|
|
hint |= nsChangeHint_NeutralChange;
|
|
|
|
}
|
|
|
|
|
2017-05-10 23:53:27 +03:00
|
|
|
if (mOverflowX != aNewData.mOverflowX || mOverflowY != aNewData.mOverflowY) {
|
2018-08-03 09:42:33 +03:00
|
|
|
hint |= nsChangeHint_ScrollbarChange;
|
2017-05-10 23:53:27 +03:00
|
|
|
}
|
|
|
|
|
2019-05-22 01:51:54 +03:00
|
|
|
/* Note: When mScrollBehavior or mScrollSnapType are changed,
|
|
|
|
* nsChangeHint_NeutralChange is not sufficient to enter
|
|
|
|
* nsCSSFrameConstructor::PropagateScrollToViewport. By using the same hint as
|
|
|
|
* used when the overflow css property changes, nsChangeHint_ReconstructFrame,
|
|
|
|
* PropagateScrollToViewport will be called.
|
2014-10-28 23:41:00 +03:00
|
|
|
*
|
|
|
|
* The scroll-behavior css property is not expected to change often (the
|
|
|
|
* CSSOM-View DOM methods are likely to be used in those cases); however,
|
|
|
|
* if this does become common perhaps a faster-path might be worth while.
|
2019-05-22 01:51:54 +03:00
|
|
|
*
|
|
|
|
* FIXME(emilio): Can we do what we do for overflow changes?
|
2014-10-28 23:41:00 +03:00
|
|
|
*/
|
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
if (mFloat != aNewData.mFloat) {
|
2017-07-15 03:20:35 +03:00
|
|
|
// Changing which side we're floating on (float:none was handled above).
|
|
|
|
hint |= nsChangeHint_ReflowHintsForFloatAreaChange;
|
2009-08-04 05:22:13 +04:00
|
|
|
}
|
2003-11-15 01:55:46 +03:00
|
|
|
|
2017-11-27 10:01:25 +03:00
|
|
|
if (mShapeOutside != aNewData.mShapeOutside ||
|
2018-02-08 04:27:04 +03:00
|
|
|
mShapeMargin != aNewData.mShapeMargin ||
|
2017-11-27 10:01:25 +03:00
|
|
|
mShapeImageThreshold != aNewData.mShapeImageThreshold) {
|
2017-07-15 03:26:30 +03:00
|
|
|
if (aNewData.mFloat != StyleFloat::None) {
|
2018-02-08 04:27:04 +03:00
|
|
|
// If we are floating, and our shape-outside, shape-margin, or
|
|
|
|
// shape-image-threshold are changed, our descendants are not impacted,
|
|
|
|
// but our ancestor and siblings are.
|
2018-10-04 20:41:22 +03:00
|
|
|
hint |= nsChangeHint_ReflowHintsForFloatAreaChange;
|
2017-07-15 03:26:30 +03:00
|
|
|
} else {
|
2018-02-08 04:27:04 +03:00
|
|
|
// shape-outside or shape-margin or shape-image-threshold changed,
|
|
|
|
// but we don't need to reflow because we're not floating.
|
2017-07-15 03:26:30 +03:00
|
|
|
hint |= nsChangeHint_NeutralChange;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-09 05:32:30 +03:00
|
|
|
if (mLineClamp != aNewData.mLineClamp) {
|
|
|
|
hint |= NS_STYLE_HINT_REFLOW;
|
|
|
|
}
|
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
if (mVerticalAlign != aNewData.mVerticalAlign) {
|
2016-04-12 08:52:41 +03:00
|
|
|
// XXX Can this just be AllReflowHints + RepaintFrame, and be included in
|
|
|
|
// the block below?
|
2016-05-23 06:26:03 +03:00
|
|
|
hint |= NS_STYLE_HINT_REFLOW;
|
2016-04-12 08:52:41 +03:00
|
|
|
}
|
|
|
|
|
2002-09-30 15:56:37 +04:00
|
|
|
// XXX the following is conservative, for now: changing float breaking
|
|
|
|
// shouldn't necessarily require a repaint, reflow should suffice.
|
2018-11-15 11:15:13 +03:00
|
|
|
//
|
|
|
|
// FIXME(emilio): We definitely change the frame tree in nsCSSFrameConstructor
|
|
|
|
// based on break-before / break-after... Shouldn't that reframe?
|
2016-06-21 04:47:54 +03:00
|
|
|
if (mBreakType != aNewData.mBreakType ||
|
|
|
|
mBreakInside != aNewData.mBreakInside ||
|
2018-11-30 08:35:47 +03:00
|
|
|
mBreakBefore != aNewData.mBreakBefore ||
|
|
|
|
mBreakAfter != aNewData.mBreakAfter ||
|
2016-06-21 04:47:54 +03:00
|
|
|
mAppearance != aNewData.mAppearance || mOrient != aNewData.mOrient ||
|
2017-12-05 23:08:41 +03:00
|
|
|
mOverflowClipBoxBlock != aNewData.mOverflowClipBoxBlock ||
|
|
|
|
mOverflowClipBoxInline != aNewData.mOverflowClipBoxInline) {
|
2016-05-23 06:26:03 +03:00
|
|
|
hint |= nsChangeHint_AllReflowHints | nsChangeHint_RepaintFrame;
|
2016-07-06 08:06:13 +03:00
|
|
|
}
|
2002-09-30 15:56:37 +04:00
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
if (mIsolation != aNewData.mIsolation) {
|
2016-05-23 06:26:03 +03:00
|
|
|
hint |= nsChangeHint_RepaintFrame;
|
2014-09-24 17:48:00 +04:00
|
|
|
}
|
|
|
|
|
2015-03-20 07:12:17 +03:00
|
|
|
/* If we've added or removed the transform property, we need to reconstruct
|
|
|
|
* the frame to add or remove the view object, and also to handle abs-pos and
|
|
|
|
* fixed-pos containers.
|
|
|
|
*/
|
2016-06-21 04:47:54 +03:00
|
|
|
if (HasTransformStyle() != aNewData.HasTransformStyle()) {
|
2018-07-30 04:51:18 +03:00
|
|
|
hint |= nsChangeHint_ComprehensiveAddOrRemoveTransform;
|
2015-03-20 07:12:17 +03:00
|
|
|
} else {
|
|
|
|
/* Otherwise, if we've kept the property lying around and we already had a
|
|
|
|
* transform, we need to see whether or not we've changed the transform.
|
|
|
|
* If so, we need to recompute its overflow rect (which probably changed
|
|
|
|
* if the transform changed) and to redraw within the bounds of that new
|
|
|
|
* overflow rect.
|
|
|
|
*
|
|
|
|
* If the property isn't present in either style struct, we still do the
|
|
|
|
* comparisons but turn all the resulting change hints into
|
|
|
|
* nsChangeHint_NeutralChange.
|
|
|
|
*/
|
|
|
|
nsChangeHint transformHint = nsChangeHint(0);
|
|
|
|
|
2019-05-17 02:25:10 +03:00
|
|
|
transformHint |= CompareTransformValues(mTransform, aNewData.mTransform);
|
|
|
|
transformHint |= CompareTransformValues(mRotate, aNewData.mRotate);
|
|
|
|
transformHint |= CompareTransformValues(mTranslate, aNewData.mTranslate);
|
|
|
|
transformHint |= CompareTransformValues(mScale, aNewData.mScale);
|
2019-05-24 06:42:03 +03:00
|
|
|
transformHint |= CompareMotionValues(*this, aNewData);
|
2015-03-20 07:12:17 +03:00
|
|
|
|
2019-02-19 23:28:47 +03:00
|
|
|
if (mTransformOrigin != aNewData.mTransformOrigin) {
|
|
|
|
transformHint |= nsChangeHint_UpdateTransformLayer |
|
|
|
|
nsChangeHint_UpdatePostTransformOverflow;
|
2016-07-06 08:06:13 +03:00
|
|
|
}
|
2015-03-20 07:12:17 +03:00
|
|
|
|
2019-02-19 23:28:47 +03:00
|
|
|
if (mPerspectiveOrigin != aNewData.mPerspectiveOrigin ||
|
|
|
|
mTransformStyle != aNewData.mTransformStyle ||
|
2016-07-06 08:06:13 +03:00
|
|
|
mTransformBox != aNewData.mTransformBox) {
|
2019-02-19 23:28:47 +03:00
|
|
|
transformHint |= nsChangeHint_UpdateOverflow | nsChangeHint_RepaintFrame;
|
2016-07-06 08:06:13 +03:00
|
|
|
}
|
2015-03-20 07:12:17 +03:00
|
|
|
|
2016-07-06 08:06:13 +03:00
|
|
|
if (mBackfaceVisibility != aNewData.mBackfaceVisibility) {
|
2016-05-23 06:26:03 +03:00
|
|
|
transformHint |= nsChangeHint_RepaintFrame;
|
2016-07-06 08:06:13 +03:00
|
|
|
}
|
2015-03-20 07:12:17 +03:00
|
|
|
|
|
|
|
if (transformHint) {
|
|
|
|
if (HasTransformStyle()) {
|
2016-05-23 06:26:03 +03:00
|
|
|
hint |= transformHint;
|
2015-03-20 07:12:17 +03:00
|
|
|
} else {
|
2016-05-23 06:26:03 +03:00
|
|
|
hint |= nsChangeHint_NeutralChange;
|
2015-03-20 07:12:17 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-03 04:35:14 +03:00
|
|
|
if (HasPerspectiveStyle() != aNewData.HasPerspectiveStyle()) {
|
|
|
|
// A change from/to being a containing block for position:fixed.
|
|
|
|
hint |= nsChangeHint_UpdateContainingBlock | nsChangeHint_UpdateOverflow |
|
|
|
|
nsChangeHint_RepaintFrame;
|
|
|
|
} else if (mChildPerspective != aNewData.mChildPerspective) {
|
|
|
|
hint |= nsChangeHint_UpdateOverflow | nsChangeHint_RepaintFrame;
|
|
|
|
}
|
|
|
|
|
2016-07-27 04:13:04 +03:00
|
|
|
// Note that the HasTransformStyle() != aNewData.HasTransformStyle()
|
2019-03-18 21:08:08 +03:00
|
|
|
// test above handles relevant changes in the StyleWillChangeBit_TRANSFORM
|
|
|
|
// bit, which in turn handles frame reconstruction for changes in the
|
|
|
|
// containing block of fixed-positioned elements.
|
|
|
|
//
|
|
|
|
// TODO(emilio): Should add xor to the generated cbindgen type.
|
|
|
|
auto willChangeBitsChanged =
|
|
|
|
StyleWillChangeBits{static_cast<decltype(StyleWillChangeBits::bits)>(
|
2019-05-17 02:23:28 +03:00
|
|
|
mWillChange.bits.bits ^ aNewData.mWillChange.bits.bits)};
|
2019-03-18 21:08:08 +03:00
|
|
|
|
2015-12-01 02:46:44 +03:00
|
|
|
if (willChangeBitsChanged &
|
2019-03-18 21:08:08 +03:00
|
|
|
(StyleWillChangeBits_STACKING_CONTEXT | StyleWillChangeBits_SCROLL |
|
|
|
|
StyleWillChangeBits_OPACITY)) {
|
2016-05-23 06:26:03 +03:00
|
|
|
hint |= nsChangeHint_RepaintFrame;
|
2015-03-20 07:12:17 +03:00
|
|
|
}
|
|
|
|
|
2018-10-18 01:13:51 +03:00
|
|
|
if (willChangeBitsChanged &
|
2019-03-18 21:08:08 +03:00
|
|
|
(StyleWillChangeBits_FIXPOS_CB | StyleWillChangeBits_ABSPOS_CB)) {
|
2016-05-23 06:26:03 +03:00
|
|
|
hint |= nsChangeHint_UpdateContainingBlock;
|
2015-12-01 02:46:44 +03:00
|
|
|
}
|
|
|
|
|
2016-06-01 20:13:14 +03:00
|
|
|
// If touch-action is changed, we need to regenerate the event regions on
|
|
|
|
// the layers and send it over to the compositor for APZ to handle.
|
2016-06-21 04:47:54 +03:00
|
|
|
if (mTouchAction != aNewData.mTouchAction) {
|
2016-06-01 20:13:14 +03:00
|
|
|
hint |= nsChangeHint_RepaintFrame;
|
|
|
|
}
|
|
|
|
|
2017-11-23 03:06:43 +03:00
|
|
|
// If overscroll-behavior has changed, the changes are picked up
|
|
|
|
// during a repaint.
|
|
|
|
if (mOverscrollBehaviorX != aNewData.mOverscrollBehaviorX ||
|
|
|
|
mOverscrollBehaviorY != aNewData.mOverscrollBehaviorY) {
|
|
|
|
hint |= nsChangeHint_SchedulePaint;
|
|
|
|
}
|
|
|
|
|
2019-06-11 12:12:10 +03:00
|
|
|
if (mOriginalDisplay != aNewData.mOriginalDisplay) {
|
|
|
|
// Our hypothetical box position may have changed.
|
|
|
|
//
|
|
|
|
// Note that it doesn't matter if we look at the old or the new struct,
|
|
|
|
// since a change on whether we need a hypothetical position would trigger
|
|
|
|
// reflow anyway.
|
|
|
|
if (IsAbsolutelyPositionedStyle() &&
|
|
|
|
aOldPosition.NeedsHypotheticalPositionIfAbsPos()) {
|
|
|
|
hint |= nsChangeHint_NeedReflow | nsChangeHint_ReflowChangesSizeOrPosition;
|
|
|
|
} else {
|
|
|
|
hint |= nsChangeHint_NeutralChange;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-12-11 19:13:19 +03:00
|
|
|
// Note: Our current behavior for handling changes to the
|
|
|
|
// transition-duration, transition-delay, and transition-timing-function
|
2009-10-08 07:22:42 +04:00
|
|
|
// properties is to do nothing. In other words, the transition
|
|
|
|
// property that matters is what it is when the transition begins, and
|
|
|
|
// we don't stop a transition later because the transition property
|
|
|
|
// changed.
|
2009-12-11 19:13:19 +03:00
|
|
|
// We do handle changes to transition-property, but we don't need to
|
|
|
|
// bother with anything here, since the transition manager is notified
|
2018-03-23 16:49:21 +03:00
|
|
|
// of any ComputedStyle change anyway.
|
2011-04-12 10:18:42 +04:00
|
|
|
|
|
|
|
// Note: Likewise, for animation-*, the animation manager gets
|
2018-03-23 16:49:21 +03:00
|
|
|
// notified about every new ComputedStyle constructed, and it uses
|
2011-04-12 10:18:42 +04:00
|
|
|
// that opportunity to handle dynamic changes appropriately.
|
|
|
|
|
2014-09-05 07:48:43 +04:00
|
|
|
// But we still need to return nsChangeHint_NeutralChange for these
|
|
|
|
// properties, since some data did change in the style struct.
|
|
|
|
|
2019-06-11 12:12:10 +03:00
|
|
|
if (!hint && (mTransitions != aNewData.mTransitions ||
|
2014-09-05 07:48:43 +04:00
|
|
|
mTransitionTimingFunctionCount !=
|
2016-06-21 04:47:54 +03:00
|
|
|
aNewData.mTransitionTimingFunctionCount ||
|
|
|
|
mTransitionDurationCount != aNewData.mTransitionDurationCount ||
|
|
|
|
mTransitionDelayCount != aNewData.mTransitionDelayCount ||
|
|
|
|
mTransitionPropertyCount != aNewData.mTransitionPropertyCount ||
|
|
|
|
mAnimations != aNewData.mAnimations ||
|
|
|
|
mAnimationTimingFunctionCount !=
|
|
|
|
aNewData.mAnimationTimingFunctionCount ||
|
|
|
|
mAnimationDurationCount != aNewData.mAnimationDurationCount ||
|
|
|
|
mAnimationDelayCount != aNewData.mAnimationDelayCount ||
|
|
|
|
mAnimationNameCount != aNewData.mAnimationNameCount ||
|
|
|
|
mAnimationDirectionCount != aNewData.mAnimationDirectionCount ||
|
|
|
|
mAnimationFillModeCount != aNewData.mAnimationFillModeCount ||
|
|
|
|
mAnimationPlayStateCount != aNewData.mAnimationPlayStateCount ||
|
|
|
|
mAnimationIterationCountCount !=
|
|
|
|
aNewData.mAnimationIterationCountCount ||
|
2019-05-17 05:37:34 +03:00
|
|
|
mWillChange != aNewData.mWillChange ||
|
|
|
|
mOverflowAnchor != aNewData.mOverflowAnchor)) {
|
2016-05-23 06:26:03 +03:00
|
|
|
hint |= nsChangeHint_NeutralChange;
|
2014-09-05 07:48:43 +04:00
|
|
|
}
|
|
|
|
|
2002-09-30 15:56:37 +04:00
|
|
|
return hint;
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------
|
|
|
|
// nsStyleVisibility
|
|
|
|
//
|
|
|
|
|
2019-01-18 20:32:22 +03:00
|
|
|
nsStyleVisibility::nsStyleVisibility(const Document& aDocument)
|
|
|
|
: mDirection(aDocument.GetBidiOptions() == IBMBIDI_TEXTDIRECTION_RTL
|
2016-05-03 12:26:29 +03:00
|
|
|
? NS_STYLE_DIRECTION_RTL
|
|
|
|
: NS_STYLE_DIRECTION_LTR),
|
|
|
|
mVisible(NS_STYLE_VISIBILITY_VISIBLE),
|
|
|
|
mImageRendering(NS_STYLE_IMAGE_RENDERING_AUTO),
|
|
|
|
mWritingMode(NS_STYLE_WRITING_MODE_HORIZONTAL_TB),
|
|
|
|
mTextOrientation(NS_STYLE_TEXT_ORIENTATION_MIXED),
|
2018-12-24 18:28:11 +03:00
|
|
|
mColorAdjust(StyleColorAdjust::Economy) {
|
2009-08-07 18:38:44 +04:00
|
|
|
MOZ_COUNT_CTOR(nsStyleVisibility);
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
nsStyleVisibility::nsStyleVisibility(const nsStyleVisibility& aSource)
|
2016-05-03 12:26:29 +03:00
|
|
|
: mImageOrientation(aSource.mImageOrientation),
|
|
|
|
mDirection(aSource.mDirection),
|
|
|
|
mVisible(aSource.mVisible),
|
|
|
|
mImageRendering(aSource.mImageRendering),
|
|
|
|
mWritingMode(aSource.mWritingMode),
|
|
|
|
mTextOrientation(aSource.mTextOrientation),
|
|
|
|
mColorAdjust(aSource.mColorAdjust) {
|
2009-08-07 18:38:44 +04:00
|
|
|
MOZ_COUNT_CTOR(nsStyleVisibility);
|
2016-05-03 12:26:29 +03:00
|
|
|
}
|
2001-06-01 02:19:43 +04:00
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
nsChangeHint nsStyleVisibility::CalcDifference(
|
|
|
|
const nsStyleVisibility& aNewData) const {
|
2010-12-11 03:25:25 +03:00
|
|
|
nsChangeHint hint = nsChangeHint(0);
|
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
if (mDirection != aNewData.mDirection ||
|
|
|
|
mWritingMode != aNewData.mWritingMode) {
|
2015-08-12 13:02:02 +03:00
|
|
|
// It's important that a change in mWritingMode results in frame
|
|
|
|
// reconstruction, because it may affect intrinsic size (see
|
|
|
|
// nsSubDocumentFrame::GetIntrinsicISize/BSize).
|
2017-02-28 20:58:30 +03:00
|
|
|
// Also, the used writing-mode value is now a field on nsIFrame and some
|
|
|
|
// classes (e.g. table rows/cells) copy their value from an ancestor.
|
2016-05-23 06:26:03 +03:00
|
|
|
hint |= nsChangeHint_ReconstructFrame;
|
2013-05-24 21:31:33 +04:00
|
|
|
} else {
|
2016-06-21 04:47:54 +03:00
|
|
|
if ((mImageOrientation != aNewData.mImageOrientation)) {
|
2016-05-23 06:26:03 +03:00
|
|
|
hint |= nsChangeHint_AllReflowHints | nsChangeHint_RepaintFrame;
|
2013-08-29 02:39:06 +04:00
|
|
|
}
|
2016-06-21 04:47:54 +03:00
|
|
|
if (mVisible != aNewData.mVisible) {
|
2018-02-09 04:43:10 +03:00
|
|
|
if (mVisible == NS_STYLE_VISIBILITY_VISIBLE ||
|
|
|
|
aNewData.mVisible == NS_STYLE_VISIBILITY_VISIBLE) {
|
|
|
|
hint |= nsChangeHint_VisibilityChange;
|
|
|
|
}
|
2013-05-24 21:31:33 +04:00
|
|
|
if ((NS_STYLE_VISIBILITY_COLLAPSE == mVisible) ||
|
2016-06-21 04:47:54 +03:00
|
|
|
(NS_STYLE_VISIBILITY_COLLAPSE == aNewData.mVisible)) {
|
2016-05-23 06:26:03 +03:00
|
|
|
hint |= NS_STYLE_HINT_REFLOW;
|
2013-05-24 21:31:33 +04:00
|
|
|
} else {
|
2016-05-23 06:26:03 +03:00
|
|
|
hint |= NS_STYLE_HINT_VISUAL;
|
2013-05-24 21:31:33 +04:00
|
|
|
}
|
|
|
|
}
|
2016-06-21 04:47:54 +03:00
|
|
|
if (mTextOrientation != aNewData.mTextOrientation) {
|
2016-05-23 06:26:03 +03:00
|
|
|
hint |= NS_STYLE_HINT_REFLOW;
|
2014-12-11 21:56:19 +03:00
|
|
|
}
|
2016-06-21 04:47:54 +03:00
|
|
|
if (mImageRendering != aNewData.mImageRendering) {
|
2016-04-12 08:52:40 +03:00
|
|
|
hint |= nsChangeHint_RepaintFrame;
|
|
|
|
}
|
2016-06-21 04:47:54 +03:00
|
|
|
if (mColorAdjust != aNewData.mColorAdjust) {
|
2016-03-08 20:25:24 +03:00
|
|
|
// color-adjust only affects media where dynamic changes can't happen.
|
2016-05-23 06:26:03 +03:00
|
|
|
hint |= nsChangeHint_NeutralChange;
|
2016-03-08 20:25:24 +03:00
|
|
|
}
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
2010-12-11 03:25:25 +03:00
|
|
|
return hint;
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
|
|
|
|
2004-07-15 02:19:22 +04:00
|
|
|
nsStyleContentData::~nsStyleContentData() {
|
2016-08-16 23:57:31 +03:00
|
|
|
MOZ_COUNT_DTOR(nsStyleContentData);
|
2016-10-21 03:14:56 +03:00
|
|
|
|
2018-06-30 16:05:15 +03:00
|
|
|
if (mType == StyleContentType::Image) {
|
2018-04-12 22:04:22 +03:00
|
|
|
// FIXME(emilio): Is this needed now that URLs are not main thread only?
|
2017-06-14 04:27:17 +03:00
|
|
|
NS_ReleaseOnMainThreadSystemGroup("nsStyleContentData::mContent.mImage",
|
|
|
|
dont_AddRef(mContent.mImage));
|
2017-03-12 09:40:54 +03:00
|
|
|
mContent.mImage = nullptr;
|
2018-06-30 16:05:15 +03:00
|
|
|
} else if (mType == StyleContentType::Counter ||
|
|
|
|
mType == StyleContentType::Counters) {
|
2005-04-02 03:07:00 +04:00
|
|
|
mContent.mCounters->Release();
|
2018-06-30 16:05:15 +03:00
|
|
|
} else if (mType == StyleContentType::String) {
|
2015-04-01 08:29:55 +03:00
|
|
|
free(mContent.mString);
|
2018-06-30 16:05:15 +03:00
|
|
|
} else if (mType == StyleContentType::Attr) {
|
2018-04-03 20:50:06 +03:00
|
|
|
delete mContent.mAttr;
|
|
|
|
} else {
|
|
|
|
MOZ_ASSERT(mContent.mString == nullptr, "Leaking due to missing case");
|
2004-07-15 02:19:22 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-16 23:57:31 +03:00
|
|
|
nsStyleContentData::nsStyleContentData(const nsStyleContentData& aOther)
|
|
|
|
: mType(aOther.mType) {
|
|
|
|
MOZ_COUNT_CTOR(nsStyleContentData);
|
2018-04-12 22:04:22 +03:00
|
|
|
switch (mType) {
|
2018-06-30 16:05:15 +03:00
|
|
|
case StyleContentType::Image:
|
2018-04-12 22:04:22 +03:00
|
|
|
mContent.mImage = aOther.mContent.mImage;
|
|
|
|
mContent.mImage->AddRef();
|
|
|
|
break;
|
2018-06-30 16:05:15 +03:00
|
|
|
case StyleContentType::Counter:
|
|
|
|
case StyleContentType::Counters:
|
2018-04-12 22:04:22 +03:00
|
|
|
mContent.mCounters = aOther.mContent.mCounters;
|
|
|
|
mContent.mCounters->AddRef();
|
|
|
|
break;
|
2018-06-30 16:05:15 +03:00
|
|
|
case StyleContentType::Attr:
|
2018-04-30 21:41:08 +03:00
|
|
|
mContent.mAttr = new nsStyleContentAttr(*aOther.mContent.mAttr);
|
2018-04-12 22:04:22 +03:00
|
|
|
break;
|
2018-06-30 16:05:15 +03:00
|
|
|
case StyleContentType::String:
|
2018-08-28 08:58:54 +03:00
|
|
|
mContent.mString = NS_xstrdup(aOther.mContent.mString);
|
2018-04-12 22:04:22 +03:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
MOZ_ASSERT(!aOther.mContent.mString);
|
|
|
|
mContent.mString = nullptr;
|
2004-07-15 02:19:22 +04:00
|
|
|
}
|
2016-08-16 23:57:31 +03:00
|
|
|
}
|
|
|
|
|
2017-05-22 15:51:20 +03:00
|
|
|
bool nsStyleContentData::CounterFunction::operator==(
|
|
|
|
const CounterFunction& aOther) const {
|
|
|
|
return mIdent == aOther.mIdent && mSeparator == aOther.mSeparator &&
|
2017-05-27 16:33:25 +03:00
|
|
|
mCounterStyle == aOther.mCounterStyle;
|
2017-05-22 15:51:20 +03:00
|
|
|
}
|
|
|
|
|
2016-08-16 23:57:31 +03:00
|
|
|
nsStyleContentData& nsStyleContentData::operator=(
|
|
|
|
const nsStyleContentData& aOther) {
|
|
|
|
if (this == &aOther) {
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
this->~nsStyleContentData();
|
|
|
|
new (this) nsStyleContentData(aOther);
|
|
|
|
|
2004-07-15 02:19:22 +04:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2016-06-03 18:56:54 +03:00
|
|
|
bool nsStyleContentData::operator==(const nsStyleContentData& aOther) const {
|
2016-07-06 08:06:13 +03:00
|
|
|
if (mType != aOther.mType) {
|
2011-10-17 18:59:28 +04:00
|
|
|
return false;
|
2016-07-06 08:06:13 +03:00
|
|
|
}
|
2018-06-30 16:05:15 +03:00
|
|
|
if (mType == StyleContentType::Image) {
|
2016-10-21 03:14:56 +03:00
|
|
|
return DefinitelyEqualImages(mContent.mImage, aOther.mContent.mImage);
|
2004-07-15 02:19:22 +04:00
|
|
|
}
|
2018-06-30 16:05:15 +03:00
|
|
|
if (mType == StyleContentType::Attr) {
|
2018-04-12 22:04:22 +03:00
|
|
|
return *mContent.mAttr == *aOther.mContent.mAttr;
|
|
|
|
}
|
2018-06-30 16:05:15 +03:00
|
|
|
if (mType == StyleContentType::Counter ||
|
|
|
|
mType == StyleContentType::Counters) {
|
2005-04-02 03:07:00 +04:00
|
|
|
return *mContent.mCounters == *aOther.mContent.mCounters;
|
2016-07-06 08:06:13 +03:00
|
|
|
}
|
2018-06-30 16:05:15 +03:00
|
|
|
if (mType == StyleContentType::String) {
|
2018-04-12 22:04:22 +03:00
|
|
|
return NS_strcmp(mContent.mString, aOther.mContent.mString) == 0;
|
|
|
|
}
|
|
|
|
MOZ_ASSERT(!mContent.mString && !aOther.mContent.mString);
|
|
|
|
return true;
|
2004-07-15 02:19:22 +04:00
|
|
|
}
|
|
|
|
|
2019-02-02 21:42:25 +03:00
|
|
|
void nsStyleContentData::Resolve(Document& aDocument,
|
2018-02-22 21:44:44 +03:00
|
|
|
const nsStyleContentData* aOldStyle) {
|
2019-02-02 21:41:44 +03:00
|
|
|
if (mType != StyleContentType::Image) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (!mContent.mImage->IsResolved()) {
|
|
|
|
const nsStyleImageRequest* oldRequest =
|
|
|
|
(aOldStyle && aOldStyle->mType == StyleContentType::Image)
|
|
|
|
? aOldStyle->mContent.mImage
|
|
|
|
: nullptr;
|
2019-02-02 21:42:25 +03:00
|
|
|
mContent.mImage->Resolve(aDocument, oldRequest);
|
2017-05-22 17:32:05 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-06-01 02:19:43 +04:00
|
|
|
//-----------------------
|
|
|
|
// nsStyleContent
|
|
|
|
//
|
|
|
|
|
2019-01-18 20:32:22 +03:00
|
|
|
nsStyleContent::nsStyleContent(const Document& aDocument) {
|
2009-08-07 18:38:44 +04:00
|
|
|
MOZ_COUNT_CTOR(nsStyleContent);
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
|
|
|
|
2016-05-03 12:26:30 +03:00
|
|
|
nsStyleContent::~nsStyleContent() { MOZ_COUNT_DTOR(nsStyleContent); }
|
2001-06-01 02:19:43 +04:00
|
|
|
|
2019-02-04 19:03:25 +03:00
|
|
|
void nsStyleContent::TriggerImageLoads(Document& aDocument,
|
|
|
|
const nsStyleContent* aOldStyle) {
|
2018-02-22 21:44:44 +03:00
|
|
|
for (size_t i = 0; i < mContents.Length(); ++i) {
|
|
|
|
const nsStyleContentData* oldData =
|
|
|
|
(aOldStyle && aOldStyle->mContents.Length() > i)
|
|
|
|
? &aOldStyle->mContents[i]
|
|
|
|
: nullptr;
|
2019-02-02 21:42:25 +03:00
|
|
|
mContents[i].Resolve(aDocument, oldData);
|
2017-03-12 09:40:54 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-06-01 02:19:43 +04:00
|
|
|
nsStyleContent::nsStyleContent(const nsStyleContent& aSource)
|
2016-10-21 13:04:46 +03:00
|
|
|
: mContents(aSource.mContents),
|
2016-08-16 23:57:31 +03:00
|
|
|
mIncrements(aSource.mIncrements),
|
2019-04-16 02:01:13 +03:00
|
|
|
mResets(aSource.mResets),
|
|
|
|
mSets(aSource.mSets) {
|
2009-08-07 18:38:44 +04:00
|
|
|
MOZ_COUNT_CTOR(nsStyleContent);
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
nsChangeHint nsStyleContent::CalcDifference(
|
|
|
|
const nsStyleContent& aNewData) const {
|
2016-08-16 23:57:31 +03:00
|
|
|
// Unfortunately we need to reframe even if the content lengths are the same;
|
|
|
|
// a simple reflow will not pick up different text or different image URLs,
|
|
|
|
// since we set all that up in the CSSFrameConstructor
|
|
|
|
if (mContents != aNewData.mContents || mIncrements != aNewData.mIncrements ||
|
2019-04-16 02:01:13 +03:00
|
|
|
mResets != aNewData.mResets || mSets != aNewData.mSets) {
|
2016-07-06 08:06:14 +03:00
|
|
|
return nsChangeHint_ReconstructFrame;
|
2005-04-02 03:07:00 +04:00
|
|
|
}
|
|
|
|
|
2016-08-16 23:57:31 +03:00
|
|
|
return nsChangeHint(0);
|
2016-08-19 10:23:42 +03:00
|
|
|
}
|
|
|
|
|
2001-06-01 02:19:43 +04:00
|
|
|
// --------------------
|
|
|
|
// nsStyleTextReset
|
|
|
|
//
|
|
|
|
|
2019-01-18 20:32:22 +03:00
|
|
|
nsStyleTextReset::nsStyleTextReset(const Document& aDocument)
|
2018-05-23 08:23:26 +03:00
|
|
|
: mTextOverflow(),
|
2019-03-18 20:58:16 +03:00
|
|
|
mTextDecorationLine(StyleTextDecorationLine_NONE),
|
2016-09-27 13:19:48 +03:00
|
|
|
mTextDecorationStyle(NS_STYLE_TEXT_DECORATION_STYLE_SOLID),
|
2016-05-03 12:26:29 +03:00
|
|
|
mUnicodeBidi(NS_STYLE_UNICODE_BIDI_NORMAL),
|
2016-07-28 10:23:36 +03:00
|
|
|
mInitialLetterSink(0),
|
|
|
|
mInitialLetterSize(0.0f),
|
2019-06-06 20:12:22 +03:00
|
|
|
mTextDecorationColor(StyleColor::CurrentColor()),
|
|
|
|
mTextDecorationWidth(LengthOrAuto::Auto()) {
|
2009-08-07 18:38:44 +04:00
|
|
|
MOZ_COUNT_CTOR(nsStyleTextReset);
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
|
|
|
|
2016-05-03 12:26:29 +03:00
|
|
|
nsStyleTextReset::nsStyleTextReset(const nsStyleTextReset& aSource)
|
2018-05-23 08:23:26 +03:00
|
|
|
: mTextOverflow(aSource.mTextOverflow),
|
|
|
|
mTextDecorationLine(aSource.mTextDecorationLine),
|
|
|
|
mTextDecorationStyle(aSource.mTextDecorationStyle),
|
|
|
|
mUnicodeBidi(aSource.mUnicodeBidi),
|
|
|
|
mInitialLetterSink(aSource.mInitialLetterSink),
|
|
|
|
mInitialLetterSize(aSource.mInitialLetterSize),
|
2019-06-06 20:12:22 +03:00
|
|
|
mTextDecorationColor(aSource.mTextDecorationColor),
|
|
|
|
mTextDecorationWidth(aSource.mTextDecorationWidth) {
|
2009-08-07 18:38:44 +04:00
|
|
|
MOZ_COUNT_CTOR(nsStyleTextReset);
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
|
|
|
|
2016-05-03 12:26:30 +03:00
|
|
|
nsStyleTextReset::~nsStyleTextReset() { MOZ_COUNT_DTOR(nsStyleTextReset); }
|
2001-06-01 02:19:43 +04:00
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
nsChangeHint nsStyleTextReset::CalcDifference(
|
|
|
|
const nsStyleTextReset& aNewData) const {
|
2016-07-28 10:23:36 +03:00
|
|
|
if (mUnicodeBidi != aNewData.mUnicodeBidi ||
|
|
|
|
mInitialLetterSink != aNewData.mInitialLetterSink ||
|
|
|
|
mInitialLetterSize != aNewData.mInitialLetterSize) {
|
2016-04-12 08:52:41 +03:00
|
|
|
return NS_STYLE_HINT_REFLOW;
|
|
|
|
}
|
2011-03-31 16:26:35 +04:00
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
if (mTextDecorationLine != aNewData.mTextDecorationLine ||
|
2019-06-06 20:12:22 +03:00
|
|
|
mTextDecorationStyle != aNewData.mTextDecorationStyle ||
|
|
|
|
mTextDecorationWidth != aNewData.mTextDecorationWidth) {
|
2016-04-12 08:52:41 +03:00
|
|
|
// Changes to our text-decoration line can impact our overflow area &
|
|
|
|
// also our descendants' overflow areas (particularly for text-frame
|
|
|
|
// descendants). So, we update those areas & trigger a repaint.
|
|
|
|
return nsChangeHint_RepaintFrame | nsChangeHint_UpdateSubtreeOverflow |
|
|
|
|
nsChangeHint_SchedulePaint;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Repaint for decoration color changes
|
2016-09-27 13:19:48 +03:00
|
|
|
if (mTextDecorationColor != aNewData.mTextDecorationColor) {
|
2016-04-12 08:52:41 +03:00
|
|
|
return nsChangeHint_RepaintFrame;
|
|
|
|
}
|
2008-03-30 00:25:15 +03:00
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
if (mTextOverflow != aNewData.mTextOverflow) {
|
2016-04-12 08:52:41 +03:00
|
|
|
return nsChangeHint_RepaintFrame;
|
2008-03-30 00:25:15 +03:00
|
|
|
}
|
2016-04-12 08:52:41 +03:00
|
|
|
|
2016-07-17 17:20:21 +03:00
|
|
|
return nsChangeHint(0);
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------
|
|
|
|
// nsStyleText
|
|
|
|
//
|
|
|
|
|
2019-05-31 17:48:22 +03:00
|
|
|
static StyleRGBA DefaultColor(const Document& aDocument) {
|
|
|
|
return StyleRGBA::FromColor(
|
|
|
|
PreferenceSheet::PrefsFor(aDocument).mDefaultColor);
|
|
|
|
}
|
|
|
|
|
2019-01-18 20:32:22 +03:00
|
|
|
nsStyleText::nsStyleText(const Document& aDocument)
|
2019-05-31 17:48:22 +03:00
|
|
|
: mColor(DefaultColor(aDocument)),
|
|
|
|
mTextTransform(StyleTextTransform::None()),
|
2019-04-14 14:06:41 +03:00
|
|
|
mTextAlign(NS_STYLE_TEXT_ALIGN_START),
|
2016-05-03 12:26:29 +03:00
|
|
|
mTextAlignLast(NS_STYLE_TEXT_ALIGN_AUTO),
|
2017-03-01 15:58:25 +03:00
|
|
|
mTextJustify(StyleTextJustify::Auto),
|
2017-06-01 21:47:54 +03:00
|
|
|
mWhiteSpace(StyleWhiteSpace::Normal),
|
2017-01-04 18:55:16 +03:00
|
|
|
mHyphens(StyleHyphens::Manual),
|
2016-05-03 12:26:29 +03:00
|
|
|
mRubyAlign(NS_STYLE_RUBY_ALIGN_SPACE_AROUND),
|
|
|
|
mRubyPosition(NS_STYLE_RUBY_POSITION_OVER),
|
|
|
|
mTextSizeAdjust(NS_STYLE_TEXT_SIZE_ADJUST_AUTO),
|
|
|
|
mTextCombineUpright(NS_STYLE_TEXT_COMBINE_UPRIGHT_NONE),
|
2017-11-20 05:46:45 +03:00
|
|
|
mControlCharacterVisibility(
|
|
|
|
nsLayoutUtils::ControlCharVisibilityDefault()),
|
2016-05-03 12:26:29 +03:00
|
|
|
mTextEmphasisStyle(NS_STYLE_TEXT_EMPHASIS_STYLE_NONE),
|
2018-11-30 08:08:46 +03:00
|
|
|
mTextRendering(StyleTextRendering::Auto),
|
2019-04-04 14:35:33 +03:00
|
|
|
mTextEmphasisColor(StyleColor::CurrentColor()),
|
|
|
|
mWebkitTextFillColor(StyleColor::CurrentColor()),
|
|
|
|
mWebkitTextStrokeColor(StyleColor::CurrentColor()),
|
2019-02-14 21:03:04 +03:00
|
|
|
mMozTabSize(
|
|
|
|
StyleNonNegativeLengthOrNumber::Number(NS_STYLE_TABSIZE_INITIAL)),
|
2019-03-04 21:19:40 +03:00
|
|
|
mWordSpacing(LengthPercentage::Zero()),
|
|
|
|
mLetterSpacing({0.}),
|
|
|
|
mLineHeight(StyleLineHeight::Normal()),
|
2019-01-26 13:00:06 +03:00
|
|
|
mTextIndent(LengthPercentage::Zero()),
|
2019-06-05 01:04:14 +03:00
|
|
|
mTextUnderlineOffset(LengthOrAuto::Auto()),
|
2019-05-17 02:04:32 +03:00
|
|
|
mWebkitTextStrokeWidth(0) {
|
2009-08-07 18:38:44 +04:00
|
|
|
MOZ_COUNT_CTOR(nsStyleText);
|
2019-01-18 20:32:22 +03:00
|
|
|
RefPtr<nsAtom> language = aDocument.GetContentLanguageAsAtomForStyle();
|
2015-11-28 03:56:33 +03:00
|
|
|
mTextEmphasisPosition =
|
2016-07-21 08:03:25 +03:00
|
|
|
language && nsStyleUtil::MatchesLanguagePrefix(language, u"zh")
|
2015-11-28 03:56:33 +03:00
|
|
|
? NS_STYLE_TEXT_EMPHASIS_POSITION_DEFAULT_ZH
|
|
|
|
: NS_STYLE_TEXT_EMPHASIS_POSITION_DEFAULT;
|
2008-06-04 03:42:13 +04:00
|
|
|
}
|
2008-06-04 02:25:31 +04:00
|
|
|
|
2008-06-06 03:06:34 +04:00
|
|
|
nsStyleText::nsStyleText(const nsStyleText& aSource)
|
2019-05-31 17:48:22 +03:00
|
|
|
: mColor(aSource.mColor),
|
|
|
|
mTextTransform(aSource.mTextTransform),
|
2019-04-14 14:06:41 +03:00
|
|
|
mTextAlign(aSource.mTextAlign),
|
2016-05-03 12:26:29 +03:00
|
|
|
mTextAlignLast(aSource.mTextAlignLast),
|
2017-03-01 15:58:25 +03:00
|
|
|
mTextJustify(aSource.mTextJustify),
|
2016-05-03 12:26:29 +03:00
|
|
|
mWhiteSpace(aSource.mWhiteSpace),
|
2019-05-20 23:46:07 +03:00
|
|
|
mLineBreak(aSource.mLineBreak),
|
2016-05-03 12:26:29 +03:00
|
|
|
mWordBreak(aSource.mWordBreak),
|
2016-05-24 03:27:21 +03:00
|
|
|
mOverflowWrap(aSource.mOverflowWrap),
|
2016-05-03 12:26:29 +03:00
|
|
|
mHyphens(aSource.mHyphens),
|
|
|
|
mRubyAlign(aSource.mRubyAlign),
|
|
|
|
mRubyPosition(aSource.mRubyPosition),
|
|
|
|
mTextSizeAdjust(aSource.mTextSizeAdjust),
|
|
|
|
mTextCombineUpright(aSource.mTextCombineUpright),
|
|
|
|
mControlCharacterVisibility(aSource.mControlCharacterVisibility),
|
|
|
|
mTextEmphasisPosition(aSource.mTextEmphasisPosition),
|
|
|
|
mTextEmphasisStyle(aSource.mTextEmphasisStyle),
|
|
|
|
mTextRendering(aSource.mTextRendering),
|
|
|
|
mTextEmphasisColor(aSource.mTextEmphasisColor),
|
|
|
|
mWebkitTextFillColor(aSource.mWebkitTextFillColor),
|
|
|
|
mWebkitTextStrokeColor(aSource.mWebkitTextStrokeColor),
|
2019-02-14 21:03:04 +03:00
|
|
|
mMozTabSize(aSource.mMozTabSize),
|
2016-05-03 12:26:29 +03:00
|
|
|
mWordSpacing(aSource.mWordSpacing),
|
|
|
|
mLetterSpacing(aSource.mLetterSpacing),
|
|
|
|
mLineHeight(aSource.mLineHeight),
|
|
|
|
mTextIndent(aSource.mTextIndent),
|
2019-06-05 01:04:14 +03:00
|
|
|
mTextUnderlineOffset(aSource.mTextUnderlineOffset),
|
2016-05-03 12:26:29 +03:00
|
|
|
mWebkitTextStrokeWidth(aSource.mWebkitTextStrokeWidth),
|
|
|
|
mTextShadow(aSource.mTextShadow),
|
|
|
|
mTextEmphasisStyleString(aSource.mTextEmphasisStyleString) {
|
2009-08-07 18:38:44 +04:00
|
|
|
MOZ_COUNT_CTOR(nsStyleText);
|
|
|
|
}
|
2008-06-06 03:06:34 +04:00
|
|
|
|
2009-08-07 18:38:44 +04:00
|
|
|
nsStyleText::~nsStyleText() { MOZ_COUNT_DTOR(nsStyleText); }
|
2001-06-01 02:19:43 +04:00
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
nsChangeHint nsStyleText::CalcDifference(const nsStyleText& aNewData) const {
|
2012-09-07 09:42:19 +04:00
|
|
|
if (WhiteSpaceOrNewlineIsSignificant() !=
|
2016-06-21 04:47:54 +03:00
|
|
|
aNewData.WhiteSpaceOrNewlineIsSignificant()) {
|
2009-06-13 13:16:34 +04:00
|
|
|
// This may require construction of suppressed text frames
|
2016-07-06 08:06:14 +03:00
|
|
|
return nsChangeHint_ReconstructFrame;
|
2009-06-13 13:16:34 +04:00
|
|
|
}
|
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
if (mTextCombineUpright != aNewData.mTextCombineUpright ||
|
|
|
|
mControlCharacterVisibility != aNewData.mControlCharacterVisibility) {
|
2013-08-19 14:26:44 +04:00
|
|
|
return nsChangeHint_ReconstructFrame;
|
|
|
|
}
|
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
if ((mTextAlign != aNewData.mTextAlign) ||
|
|
|
|
(mTextAlignLast != aNewData.mTextAlignLast) ||
|
|
|
|
(mTextTransform != aNewData.mTextTransform) ||
|
|
|
|
(mWhiteSpace != aNewData.mWhiteSpace) ||
|
2019-05-20 23:46:07 +03:00
|
|
|
(mLineBreak != aNewData.mLineBreak) ||
|
2016-06-21 04:47:54 +03:00
|
|
|
(mWordBreak != aNewData.mWordBreak) ||
|
|
|
|
(mOverflowWrap != aNewData.mOverflowWrap) ||
|
|
|
|
(mHyphens != aNewData.mHyphens) || (mRubyAlign != aNewData.mRubyAlign) ||
|
|
|
|
(mRubyPosition != aNewData.mRubyPosition) ||
|
|
|
|
(mTextSizeAdjust != aNewData.mTextSizeAdjust) ||
|
|
|
|
(mLetterSpacing != aNewData.mLetterSpacing) ||
|
|
|
|
(mLineHeight != aNewData.mLineHeight) ||
|
|
|
|
(mTextIndent != aNewData.mTextIndent) ||
|
2019-06-05 01:04:14 +03:00
|
|
|
(mTextUnderlineOffset != aNewData.mTextUnderlineOffset) ||
|
2017-03-01 15:58:25 +03:00
|
|
|
(mTextJustify != aNewData.mTextJustify) ||
|
2016-06-21 04:47:54 +03:00
|
|
|
(mWordSpacing != aNewData.mWordSpacing) ||
|
2019-02-14 21:03:04 +03:00
|
|
|
(mMozTabSize != aNewData.mMozTabSize)) {
|
2008-06-06 03:06:34 +04:00
|
|
|
return NS_STYLE_HINT_REFLOW;
|
2016-07-06 08:06:13 +03:00
|
|
|
}
|
2008-06-06 03:06:34 +04:00
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
if (HasTextEmphasis() != aNewData.HasTextEmphasis() ||
|
2015-12-08 20:55:01 +03:00
|
|
|
(HasTextEmphasis() &&
|
2016-06-21 04:47:54 +03:00
|
|
|
mTextEmphasisPosition != aNewData.mTextEmphasisPosition)) {
|
2015-12-08 20:55:01 +03:00
|
|
|
// Text emphasis position change could affect line height calculation.
|
|
|
|
return nsChangeHint_AllReflowHints | nsChangeHint_RepaintFrame;
|
|
|
|
}
|
|
|
|
|
2016-04-12 08:52:41 +03:00
|
|
|
nsChangeHint hint = nsChangeHint(0);
|
|
|
|
|
|
|
|
// text-rendering changes require a reflow since they change SVG
|
|
|
|
// frames' rects.
|
2016-06-21 04:47:54 +03:00
|
|
|
if (mTextRendering != aNewData.mTextRendering) {
|
2016-04-12 08:52:41 +03:00
|
|
|
hint |= nsChangeHint_NeedReflow |
|
|
|
|
nsChangeHint_NeedDirtyReflow | // XXX remove me: bug 876085
|
|
|
|
nsChangeHint_RepaintFrame;
|
|
|
|
}
|
|
|
|
|
2019-05-17 02:04:32 +03:00
|
|
|
if (mTextShadow != aNewData.mTextShadow ||
|
2016-06-21 04:47:54 +03:00
|
|
|
mTextEmphasisStyle != aNewData.mTextEmphasisStyle ||
|
|
|
|
mTextEmphasisStyleString != aNewData.mTextEmphasisStyleString ||
|
|
|
|
mWebkitTextStrokeWidth != aNewData.mWebkitTextStrokeWidth) {
|
2016-04-12 08:52:41 +03:00
|
|
|
hint |= nsChangeHint_UpdateSubtreeOverflow | nsChangeHint_SchedulePaint |
|
|
|
|
nsChangeHint_RepaintFrame;
|
|
|
|
|
|
|
|
// We don't add any other hints below.
|
|
|
|
return hint;
|
2015-11-28 03:56:33 +03:00
|
|
|
}
|
|
|
|
|
2019-05-31 17:48:22 +03:00
|
|
|
if (mColor != aNewData.mColor) {
|
|
|
|
hint |= nsChangeHint_RepaintFrame;
|
|
|
|
}
|
|
|
|
|
2016-09-16 07:40:45 +03:00
|
|
|
if (mTextEmphasisColor != aNewData.mTextEmphasisColor ||
|
2016-06-21 04:47:54 +03:00
|
|
|
mWebkitTextFillColor != aNewData.mWebkitTextFillColor ||
|
|
|
|
mWebkitTextStrokeColor != aNewData.mWebkitTextStrokeColor) {
|
2016-05-23 06:26:03 +03:00
|
|
|
hint |= nsChangeHint_SchedulePaint | nsChangeHint_RepaintFrame;
|
2016-04-12 08:52:41 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if (hint) {
|
|
|
|
return hint;
|
2015-11-28 03:56:33 +03:00
|
|
|
}
|
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
if (mTextEmphasisPosition != aNewData.mTextEmphasisPosition) {
|
2015-12-08 20:55:01 +03:00
|
|
|
return nsChangeHint_NeutralChange;
|
|
|
|
}
|
|
|
|
|
2016-07-17 17:20:21 +03:00
|
|
|
return nsChangeHint(0);
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
|
|
|
|
2015-11-28 03:56:33 +03:00
|
|
|
LogicalSide nsStyleText::TextEmphasisSide(WritingMode aWM) const {
|
|
|
|
MOZ_ASSERT(
|
|
|
|
(!(mTextEmphasisPosition & NS_STYLE_TEXT_EMPHASIS_POSITION_LEFT) !=
|
|
|
|
!(mTextEmphasisPosition & NS_STYLE_TEXT_EMPHASIS_POSITION_RIGHT)) &&
|
|
|
|
(!(mTextEmphasisPosition & NS_STYLE_TEXT_EMPHASIS_POSITION_OVER) !=
|
|
|
|
!(mTextEmphasisPosition & NS_STYLE_TEXT_EMPHASIS_POSITION_UNDER)));
|
2016-02-25 03:09:34 +03:00
|
|
|
mozilla::Side side =
|
|
|
|
aWM.IsVertical()
|
2015-11-28 03:56:33 +03:00
|
|
|
? (mTextEmphasisPosition & NS_STYLE_TEXT_EMPHASIS_POSITION_LEFT
|
|
|
|
? eSideLeft
|
|
|
|
: eSideRight)
|
|
|
|
: (mTextEmphasisPosition & NS_STYLE_TEXT_EMPHASIS_POSITION_OVER
|
|
|
|
? eSideTop
|
|
|
|
: eSideBottom);
|
|
|
|
LogicalSide result = aWM.LogicalSideForPhysicalSide(side);
|
|
|
|
MOZ_ASSERT(IsBlock(result));
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2001-06-01 02:19:43 +04:00
|
|
|
//-----------------------
|
2018-08-14 11:37:37 +03:00
|
|
|
// nsStyleUI
|
2001-06-01 02:19:43 +04:00
|
|
|
//
|
|
|
|
|
2005-07-01 08:29:42 +04:00
|
|
|
nsCursorImage::nsCursorImage()
|
2011-10-17 18:59:28 +04:00
|
|
|
: mHaveHotspot(false), mHotspotX(0.0f), mHotspotY(0.0f) {}
|
2005-07-01 08:29:42 +04:00
|
|
|
|
2010-08-16 20:19:26 +04:00
|
|
|
nsCursorImage::nsCursorImage(const nsCursorImage& aOther)
|
|
|
|
: mHaveHotspot(aOther.mHaveHotspot),
|
|
|
|
mHotspotX(aOther.mHotspotX),
|
|
|
|
mHotspotY(aOther.mHotspotY),
|
2016-11-21 09:34:11 +03:00
|
|
|
mImage(aOther.mImage) {}
|
2010-08-16 20:19:26 +04:00
|
|
|
|
|
|
|
nsCursorImage& nsCursorImage::operator=(const nsCursorImage& aOther) {
|
|
|
|
if (this != &aOther) {
|
|
|
|
mHaveHotspot = aOther.mHaveHotspot;
|
|
|
|
mHotspotX = aOther.mHotspotX;
|
|
|
|
mHotspotY = aOther.mHotspotY;
|
2016-11-21 09:34:11 +03:00
|
|
|
mImage = aOther.mImage;
|
2010-08-16 20:19:26 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2016-09-29 05:55:55 +03:00
|
|
|
bool nsCursorImage::operator==(const nsCursorImage& aOther) const {
|
|
|
|
NS_ASSERTION(mHaveHotspot || (mHotspotX == 0 && mHotspotY == 0),
|
|
|
|
"expected mHotspot{X,Y} to be 0 when mHaveHotspot is false");
|
|
|
|
NS_ASSERTION(
|
|
|
|
aOther.mHaveHotspot || (aOther.mHotspotX == 0 && aOther.mHotspotY == 0),
|
|
|
|
"expected mHotspot{X,Y} to be 0 when mHaveHotspot is false");
|
|
|
|
return mHaveHotspot == aOther.mHaveHotspot && mHotspotX == aOther.mHotspotX &&
|
|
|
|
mHotspotY == aOther.mHotspotY &&
|
2016-11-21 09:34:11 +03:00
|
|
|
DefinitelyEqualImages(mImage, aOther.mImage);
|
2016-09-29 05:55:55 +03:00
|
|
|
}
|
|
|
|
|
2019-01-18 20:32:22 +03:00
|
|
|
nsStyleUI::nsStyleUI(const Document& aDocument)
|
2016-10-23 01:08:18 +03:00
|
|
|
: mUserInput(StyleUserInput::Auto),
|
2016-10-23 23:41:49 +03:00
|
|
|
mUserModify(StyleUserModify::ReadOnly),
|
2016-09-03 21:46:58 +03:00
|
|
|
mUserFocus(StyleUserFocus::None),
|
2016-05-03 12:26:30 +03:00
|
|
|
mPointerEvents(NS_STYLE_POINTER_EVENTS_AUTO),
|
2019-01-15 17:05:45 +03:00
|
|
|
mCursor(StyleCursorKind::Auto),
|
2019-04-04 14:35:16 +03:00
|
|
|
mCaretColor(StyleColorOrAuto::Auto()),
|
|
|
|
mScrollbarColor(StyleScrollbarColor::Auto()) {
|
2018-08-14 11:37:37 +03:00
|
|
|
MOZ_COUNT_CTOR(nsStyleUI);
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
|
|
|
|
2018-08-14 11:37:37 +03:00
|
|
|
nsStyleUI::nsStyleUI(const nsStyleUI& aSource)
|
2016-05-03 12:26:30 +03:00
|
|
|
: mUserInput(aSource.mUserInput),
|
|
|
|
mUserModify(aSource.mUserModify),
|
|
|
|
mUserFocus(aSource.mUserFocus),
|
|
|
|
mPointerEvents(aSource.mPointerEvents),
|
|
|
|
mCursor(aSource.mCursor),
|
2016-09-29 05:55:55 +03:00
|
|
|
mCursorImages(aSource.mCursorImages),
|
2016-12-22 03:04:15 +03:00
|
|
|
mCaretColor(aSource.mCaretColor),
|
2019-04-04 14:35:16 +03:00
|
|
|
mScrollbarColor(aSource.mScrollbarColor) {
|
2018-08-14 11:37:37 +03:00
|
|
|
MOZ_COUNT_CTOR(nsStyleUI);
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
|
|
|
|
2018-08-14 11:37:37 +03:00
|
|
|
nsStyleUI::~nsStyleUI() { MOZ_COUNT_DTOR(nsStyleUI); }
|
2001-06-01 02:19:43 +04:00
|
|
|
|
2019-02-04 19:03:25 +03:00
|
|
|
void nsStyleUI::TriggerImageLoads(Document& aDocument,
|
|
|
|
const nsStyleUI* aOldStyle) {
|
2016-11-21 09:34:11 +03:00
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
|
2018-02-22 21:44:44 +03:00
|
|
|
for (size_t i = 0; i < mCursorImages.Length(); ++i) {
|
|
|
|
nsCursorImage& cursor = mCursorImages[i];
|
|
|
|
|
2016-11-21 09:34:11 +03:00
|
|
|
if (cursor.mImage && !cursor.mImage->IsResolved()) {
|
2018-02-22 21:44:44 +03:00
|
|
|
const nsCursorImage* oldCursor =
|
|
|
|
(aOldStyle && aOldStyle->mCursorImages.Length() > i)
|
|
|
|
? &aOldStyle->mCursorImages[i]
|
|
|
|
: nullptr;
|
2019-02-02 21:42:25 +03:00
|
|
|
cursor.mImage->Resolve(aDocument,
|
2018-02-22 21:44:44 +03:00
|
|
|
oldCursor ? oldCursor->mImage.get() : nullptr);
|
2016-11-21 09:34:11 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-08-14 11:37:37 +03:00
|
|
|
nsChangeHint nsStyleUI::CalcDifference(const nsStyleUI& aNewData) const {
|
2004-12-28 16:48:25 +03:00
|
|
|
nsChangeHint hint = nsChangeHint(0);
|
2016-07-06 08:06:13 +03:00
|
|
|
if (mCursor != aNewData.mCursor) {
|
2016-05-23 06:26:03 +03:00
|
|
|
hint |= nsChangeHint_UpdateCursor;
|
2016-07-06 08:06:13 +03:00
|
|
|
}
|
2001-06-01 02:19:43 +04:00
|
|
|
|
2004-12-31 00:56:11 +03:00
|
|
|
// We could do better. But it wouldn't be worth it, URL-specified cursors are
|
|
|
|
// rare.
|
2016-09-29 05:55:55 +03:00
|
|
|
if (mCursorImages != aNewData.mCursorImages) {
|
2016-05-23 06:26:03 +03:00
|
|
|
hint |= nsChangeHint_UpdateCursor;
|
2016-07-06 08:06:13 +03:00
|
|
|
}
|
2004-12-31 00:56:11 +03:00
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
if (mPointerEvents != aNewData.mPointerEvents) {
|
2016-12-18 14:11:47 +03:00
|
|
|
// SVGGeometryFrame's mRect depends on stroke _and_ on the value
|
|
|
|
// of pointer-events. See SVGGeometryFrame::ReflowSVG's use of
|
2016-04-12 08:52:41 +03:00
|
|
|
// GetHitTestFlags. (Only a reflow, no visual change.)
|
|
|
|
hint |= nsChangeHint_NeedReflow |
|
|
|
|
nsChangeHint_NeedDirtyReflow; // XXX remove me: bug 876085
|
|
|
|
}
|
|
|
|
|
2016-07-06 08:06:13 +03:00
|
|
|
if (mUserModify != aNewData.mUserModify) {
|
2016-05-23 06:26:03 +03:00
|
|
|
hint |= NS_STYLE_HINT_VISUAL;
|
2016-07-06 08:06:13 +03:00
|
|
|
}
|
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
if (mUserInput != aNewData.mUserInput) {
|
2016-10-23 01:08:18 +03:00
|
|
|
if (StyleUserInput::None == mUserInput ||
|
|
|
|
StyleUserInput::None == aNewData.mUserInput) {
|
2016-07-06 08:06:14 +03:00
|
|
|
hint |= nsChangeHint_ReconstructFrame;
|
2014-09-05 07:48:43 +04:00
|
|
|
} else {
|
2016-05-23 06:26:03 +03:00
|
|
|
hint |= nsChangeHint_NeutralChange;
|
2014-09-05 07:48:43 +04:00
|
|
|
}
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
if (mUserFocus != aNewData.mUserFocus) {
|
2016-05-23 06:26:03 +03:00
|
|
|
hint |= nsChangeHint_NeutralChange;
|
2014-09-05 07:48:43 +04:00
|
|
|
}
|
2004-12-28 16:48:25 +03:00
|
|
|
|
2018-05-10 03:40:17 +03:00
|
|
|
if (mCaretColor != aNewData.mCaretColor ||
|
2019-04-04 14:35:16 +03:00
|
|
|
mScrollbarColor != aNewData.mScrollbarColor) {
|
2016-12-22 03:04:15 +03:00
|
|
|
hint |= nsChangeHint_RepaintFrame;
|
|
|
|
}
|
|
|
|
|
2004-12-28 16:48:25 +03:00
|
|
|
return hint;
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------
|
|
|
|
// nsStyleUIReset
|
|
|
|
//
|
|
|
|
|
2019-01-18 20:32:22 +03:00
|
|
|
nsStyleUIReset::nsStyleUIReset(const Document& aDocument)
|
2016-08-10 19:12:21 +03:00
|
|
|
: mUserSelect(StyleUserSelect::Auto),
|
2018-08-01 07:13:41 +03:00
|
|
|
mScrollbarWidth(StyleScrollbarWidth::Auto),
|
2016-05-03 12:26:30 +03:00
|
|
|
mForceBrokenImageIcon(0),
|
|
|
|
mIMEMode(NS_STYLE_IME_MODE_AUTO),
|
2016-10-29 11:51:05 +03:00
|
|
|
mWindowDragging(StyleWindowDragging::Default),
|
2016-05-03 12:26:30 +03:00
|
|
|
mWindowShadow(NS_STYLE_WINDOW_SHADOW_DEFAULT),
|
2017-06-19 04:04:40 +03:00
|
|
|
mWindowOpacity(1.0),
|
2019-02-19 23:28:47 +03:00
|
|
|
mWindowTransformOrigin{LengthPercentage::FromPercentage(0.5),
|
|
|
|
LengthPercentage::FromPercentage(0.5),
|
|
|
|
{0.}} {
|
2009-08-07 18:38:44 +04:00
|
|
|
MOZ_COUNT_CTOR(nsStyleUIReset);
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
|
|
|
|
2016-05-03 12:26:30 +03:00
|
|
|
nsStyleUIReset::nsStyleUIReset(const nsStyleUIReset& aSource)
|
|
|
|
: mUserSelect(aSource.mUserSelect),
|
2018-08-01 07:13:41 +03:00
|
|
|
mScrollbarWidth(aSource.mScrollbarWidth),
|
2016-05-03 12:26:30 +03:00
|
|
|
mForceBrokenImageIcon(aSource.mForceBrokenImageIcon),
|
|
|
|
mIMEMode(aSource.mIMEMode),
|
|
|
|
mWindowDragging(aSource.mWindowDragging),
|
|
|
|
mWindowShadow(aSource.mWindowShadow),
|
2017-06-19 04:04:40 +03:00
|
|
|
mWindowOpacity(aSource.mWindowOpacity),
|
2019-05-17 02:25:10 +03:00
|
|
|
mMozWindowTransform(aSource.mMozWindowTransform),
|
2019-02-19 23:28:47 +03:00
|
|
|
mWindowTransformOrigin(aSource.mWindowTransformOrigin) {
|
2009-08-07 18:38:44 +04:00
|
|
|
MOZ_COUNT_CTOR(nsStyleUIReset);
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
|
|
|
|
2019-05-22 00:07:55 +03:00
|
|
|
nsStyleUIReset::~nsStyleUIReset() { MOZ_COUNT_DTOR(nsStyleUIReset); }
|
2001-06-01 02:19:43 +04:00
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
nsChangeHint nsStyleUIReset::CalcDifference(
|
|
|
|
const nsStyleUIReset& aNewData) const {
|
2017-06-19 04:04:40 +03:00
|
|
|
nsChangeHint hint = nsChangeHint(0);
|
|
|
|
|
2016-07-06 08:06:13 +03:00
|
|
|
if (mForceBrokenImageIcon != aNewData.mForceBrokenImageIcon) {
|
2017-06-19 04:04:40 +03:00
|
|
|
hint |= nsChangeHint_ReconstructFrame;
|
2016-07-06 08:06:13 +03:00
|
|
|
}
|
2018-08-01 07:13:41 +03:00
|
|
|
if (mScrollbarWidth != aNewData.mScrollbarWidth) {
|
|
|
|
// For scrollbar-width change, we need some special handling similar
|
|
|
|
// to overflow properties. Specifically, we may need to reconstruct
|
|
|
|
// the scrollbar or force reflow of the viewport scrollbar.
|
|
|
|
hint |= nsChangeHint_ScrollbarChange;
|
|
|
|
}
|
2016-06-21 04:47:54 +03:00
|
|
|
if (mWindowShadow != aNewData.mWindowShadow) {
|
2008-10-14 18:44:25 +04:00
|
|
|
// We really need just an nsChangeHint_SyncFrameView, except
|
|
|
|
// on an ancestor of the frame, so we get that by doing a
|
|
|
|
// reflow.
|
2017-06-19 04:04:40 +03:00
|
|
|
hint |= NS_STYLE_HINT_REFLOW;
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
2016-07-06 08:06:13 +03:00
|
|
|
if (mUserSelect != aNewData.mUserSelect) {
|
2017-06-19 04:04:40 +03:00
|
|
|
hint |= NS_STYLE_HINT_VISUAL;
|
2016-07-06 08:06:13 +03:00
|
|
|
}
|
2016-01-27 13:58:33 +03:00
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
if (mWindowDragging != aNewData.mWindowDragging) {
|
2017-06-19 04:04:40 +03:00
|
|
|
hint |= nsChangeHint_SchedulePaint;
|
2017-01-19 11:13:02 +03:00
|
|
|
}
|
|
|
|
|
2017-06-19 08:44:22 +03:00
|
|
|
if (mWindowOpacity != aNewData.mWindowOpacity ||
|
2019-05-17 02:25:10 +03:00
|
|
|
mMozWindowTransform != aNewData.mMozWindowTransform) {
|
2017-06-19 04:04:40 +03:00
|
|
|
hint |= nsChangeHint_UpdateWidgetProperties;
|
2017-06-19 04:04:40 +03:00
|
|
|
}
|
|
|
|
|
2017-06-19 04:04:40 +03:00
|
|
|
if (!hint && mIMEMode != aNewData.mIMEMode) {
|
|
|
|
hint |= nsChangeHint_NeutralChange;
|
|
|
|
}
|
|
|
|
|
|
|
|
return hint;
|
2001-06-01 02:19:43 +04:00
|
|
|
}
|
2013-12-12 06:09:40 +04:00
|
|
|
|
2016-04-12 08:52:42 +03:00
|
|
|
//-----------------------
|
|
|
|
// nsStyleEffects
|
|
|
|
//
|
|
|
|
|
2019-01-18 20:32:22 +03:00
|
|
|
nsStyleEffects::nsStyleEffects(const Document&)
|
2019-05-17 02:04:32 +03:00
|
|
|
: mClip(0, 0, 0, 0),
|
2016-04-12 08:52:43 +03:00
|
|
|
mOpacity(1.0f),
|
2016-04-12 08:52:42 +03:00
|
|
|
mClipFlags(NS_STYLE_CLIP_AUTO),
|
2016-04-12 08:52:42 +03:00
|
|
|
mMixBlendMode(NS_STYLE_BLEND_NORMAL) {
|
2016-04-12 08:52:42 +03:00
|
|
|
MOZ_COUNT_CTOR(nsStyleEffects);
|
|
|
|
}
|
|
|
|
|
|
|
|
nsStyleEffects::nsStyleEffects(const nsStyleEffects& aSource)
|
2016-04-12 08:52:43 +03:00
|
|
|
: mFilters(aSource.mFilters),
|
|
|
|
mBoxShadow(aSource.mBoxShadow),
|
2019-06-27 02:02:16 +03:00
|
|
|
mBackdropFilters(aSource.mBackdropFilters),
|
2016-04-12 08:52:42 +03:00
|
|
|
mClip(aSource.mClip),
|
2016-04-12 08:52:43 +03:00
|
|
|
mOpacity(aSource.mOpacity),
|
2016-04-12 08:52:42 +03:00
|
|
|
mClipFlags(aSource.mClipFlags),
|
2016-04-12 08:52:42 +03:00
|
|
|
mMixBlendMode(aSource.mMixBlendMode) {
|
2016-04-12 08:52:42 +03:00
|
|
|
MOZ_COUNT_CTOR(nsStyleEffects);
|
|
|
|
}
|
|
|
|
|
|
|
|
nsStyleEffects::~nsStyleEffects() { MOZ_COUNT_DTOR(nsStyleEffects); }
|
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
nsChangeHint nsStyleEffects::CalcDifference(
|
|
|
|
const nsStyleEffects& aNewData) const {
|
2016-04-12 08:52:42 +03:00
|
|
|
nsChangeHint hint = nsChangeHint(0);
|
|
|
|
|
2019-05-17 02:04:32 +03:00
|
|
|
if (mBoxShadow != aNewData.mBoxShadow) {
|
2016-04-12 08:52:42 +03:00
|
|
|
// Update overflow regions & trigger DLBI to be sure it's noticed.
|
|
|
|
// Also request a repaint, since it's possible that only the color
|
|
|
|
// of the shadow is changing (and UpdateOverflow/SchedulePaint won't
|
|
|
|
// repaint for that, since they won't know what needs invalidating.)
|
|
|
|
hint |= nsChangeHint_UpdateOverflow | nsChangeHint_SchedulePaint |
|
|
|
|
nsChangeHint_RepaintFrame;
|
|
|
|
}
|
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
if (mClipFlags != aNewData.mClipFlags) {
|
2016-04-12 08:52:42 +03:00
|
|
|
hint |= nsChangeHint_AllReflowHints | nsChangeHint_RepaintFrame;
|
|
|
|
}
|
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
if (!mClip.IsEqualInterior(aNewData.mClip)) {
|
2016-04-12 08:52:42 +03:00
|
|
|
// If the clip has changed, we just need to update overflow areas. DLBI
|
|
|
|
// will handle the invalidation.
|
|
|
|
hint |= nsChangeHint_UpdateOverflow | nsChangeHint_SchedulePaint;
|
|
|
|
}
|
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
if (mOpacity != aNewData.mOpacity) {
|
2016-04-12 08:52:43 +03:00
|
|
|
// If we're going from the optimized >=0.99 opacity value to 1.0 or back,
|
|
|
|
// then repaint the frame because DLBI will not catch the invalidation.
|
|
|
|
// Otherwise, just update the opacity layer.
|
2016-06-21 04:47:54 +03:00
|
|
|
if ((mOpacity >= 0.99f && mOpacity < 1.0f && aNewData.mOpacity == 1.0f) ||
|
|
|
|
(aNewData.mOpacity >= 0.99f && aNewData.mOpacity < 1.0f &&
|
|
|
|
mOpacity == 1.0f)) {
|
2016-04-12 08:52:43 +03:00
|
|
|
hint |= nsChangeHint_RepaintFrame;
|
|
|
|
} else {
|
|
|
|
hint |= nsChangeHint_UpdateOpacityLayer;
|
2016-06-21 04:47:54 +03:00
|
|
|
if ((mOpacity == 1.0f) != (aNewData.mOpacity == 1.0f)) {
|
2016-04-12 08:52:43 +03:00
|
|
|
hint |= nsChangeHint_UpdateUsesOpacity;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
if (HasFilters() != aNewData.HasFilters()) {
|
2016-04-12 08:52:43 +03:00
|
|
|
// A change from/to being a containing block for position:fixed.
|
|
|
|
hint |= nsChangeHint_UpdateContainingBlock;
|
|
|
|
}
|
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
if (mFilters != aNewData.mFilters) {
|
2016-04-12 08:52:43 +03:00
|
|
|
hint |= nsChangeHint_UpdateEffects | nsChangeHint_RepaintFrame |
|
|
|
|
nsChangeHint_UpdateOverflow;
|
|
|
|
}
|
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
if (mMixBlendMode != aNewData.mMixBlendMode) {
|
2016-04-12 08:52:42 +03:00
|
|
|
hint |= nsChangeHint_RepaintFrame;
|
|
|
|
}
|
|
|
|
|
2019-06-27 02:02:16 +03:00
|
|
|
if (mBackdropFilters != aNewData.mBackdropFilters) {
|
|
|
|
hint |= nsChangeHint_UpdateEffects | nsChangeHint_RepaintFrame;
|
|
|
|
}
|
|
|
|
|
2016-06-21 04:47:54 +03:00
|
|
|
if (!hint && !mClip.IsEqualEdges(aNewData.mClip)) {
|
2016-04-12 08:52:42 +03:00
|
|
|
hint |= nsChangeHint_NeutralChange;
|
|
|
|
}
|
|
|
|
|
2016-04-12 08:52:42 +03:00
|
|
|
return hint;
|
|
|
|
}
|