summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMoonchild <moonchild@palemoon.org>2020-10-24 10:42:23 +0000
committerMoonchild <moonchild@palemoon.org>2020-10-24 10:42:23 +0000
commite1db27e19989db11fef70f439cf95821316535b3 (patch)
treeabac2c9f5115323a8816d3ef600d8cb2bca5a33e
parenta98d06380fe706e3b1b602411c597b9882516b3e (diff)
parenta5203631d8cded437c05243cde17cddeba13e3ec (diff)
downloadUXP-RELBASE_20201024.tar
UXP-RELBASE_20201024.tar.gz
UXP-RELBASE_20201024.tar.lz
UXP-RELBASE_20201024.tar.xz
UXP-RELBASE_20201024.zip
Merge branch 'redwood' into releaseRELBASE_20201024RC_20201024
-rw-r--r--README.md2
-rw-r--r--SECURITY.md2
-rw-r--r--config/milestone.txt2
-rw-r--r--devtools/client/inspector/rules/test/browser_rules_pseudo-element_01.js6
-rw-r--r--devtools/shared/css/generated/properties-db.js24
-rw-r--r--dom/base/ResizeObserverController.cpp22
-rw-r--r--dom/base/ResizeObserverController.h5
-rw-r--r--dom/base/nsDocument.cpp6
-rw-r--r--dom/base/nsImageLoadingContent.cpp6
-rw-r--r--dom/fetch/FetchDriver.cpp24
-rw-r--r--dom/smil/nsSMILCSSProperty.cpp1
-rw-r--r--layout/generic/nsFrame.cpp3
-rw-r--r--layout/generic/nsTextFrame.cpp11
-rw-r--r--layout/inspector/tests/test_getCSSPseudoElementNames.html1
-rw-r--r--layout/reftests/image/reftest.list2
-rw-r--r--layout/reftests/image/unknown-protocol-ref.html1
-rw-r--r--layout/reftests/image/unknown-protocol.html1
-rw-r--r--layout/style/StyleAnimationValue.cpp12
-rw-r--r--layout/style/StyleComplexColor.h21
-rw-r--r--layout/style/nsCSSPropList.h11
-rw-r--r--layout/style/nsCSSPseudoElementList.h3
-rw-r--r--layout/style/nsComputedDOMStyle.cpp8
-rw-r--r--layout/style/nsComputedDOMStyle.h1
-rw-r--r--layout/style/nsComputedDOMStylePropertyList.h1
-rw-r--r--layout/style/nsRuleNode.cpp18
-rw-r--r--layout/style/nsStyleContext.cpp17
-rw-r--r--layout/style/nsStyleStruct.cpp6
-rw-r--r--layout/style/nsStyleStruct.h1
-rw-r--r--layout/style/test/property_database.js12
-rw-r--r--layout/style/test/test_transitions_per_property.html15
-rw-r--r--layout/tables/nsTableFrame.cpp36
-rw-r--r--netwerk/base/nsIncrementalStreamLoader.cpp10
-rw-r--r--netwerk/base/nsIncrementalStreamLoader.h5
-rw-r--r--netwerk/base/nsStreamLoader.cpp7
-rw-r--r--netwerk/base/nsStreamLoader.h2
35 files changed, 250 insertions, 55 deletions
diff --git a/README.md b/README.md
index 1acd353d9..e24a7476c 100644
--- a/README.md
+++ b/README.md
@@ -36,4 +36,4 @@ improvement patches upstream to its origin to mutually improve the platform and
a future for XUL.
## Looking for Pale Moon and Basilisk?
-As of [`Issue #969`](https://github.com/MoonchildProductions/UXP/issues/969), release versions `28.9.0` and `2020.03.04` respectively, they have been split off into their own dedicated repositories located at [`MoonchildProductions/Pale-Moon`](https://github.com/MoonchildProductions/Pale-Moon) and [`MoonchildProductions/Basilisk`](https://github.com/MoonchildProductions/Basilisk).
+As of [`Issue #969`](https://repo.palemoon.org/MoonchildProductions/UXP/issues/969), release versions `28.9.0` and `2020.03.04` respectively, they have been split off into their own dedicated repositories located at [`MoonchildProductions/Pale-Moon`](https://repo.palemoon.org/MoonchildProductions/Pale-Moon) and [`MoonchildProductions/Basilisk`](https://repo.palemoon.org/MoonchildProductions/Basilisk).
diff --git a/SECURITY.md b/SECURITY.md
index af9c916cd..8ef831674 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -23,7 +23,7 @@ Generally not security vulnerabilities:
## Reporting a Vulnerability
If you find an issue in UXP or the applications it builds on that could impact the security or safety of users please **do not**
-make an issue on GitHub about it. GitHub does not support restricted viewability for security sensitive bugs.
+make an issue on Gitea about it. Gitea does not support restricted viewability for security sensitive bugs.
If you want to report a security-sensitive issue then please go to the [forum](https://forum.palemoon.org) and report the issue
via a **private message** to **Moonchild** (the founder and prime responsible for security issues).
diff --git a/config/milestone.txt b/config/milestone.txt
index 8642dc41d..642399584 100644
--- a/config/milestone.txt
+++ b/config/milestone.txt
@@ -10,4 +10,4 @@
# hardcoded milestones in the tree from these two files.
#--------------------------------------------------------
-4.6.0 \ No newline at end of file
+4.7.0 \ No newline at end of file
diff --git a/devtools/client/inspector/rules/test/browser_rules_pseudo-element_01.js b/devtools/client/inspector/rules/test/browser_rules_pseudo-element_01.js
index e98b5437c..025ee6519 100644
--- a/devtools/client/inspector/rules/test/browser_rules_pseudo-element_01.js
+++ b/devtools/client/inspector/rules/test/browser_rules_pseudo-element_01.js
@@ -30,7 +30,7 @@ function* testTopLeft(inspector, view) {
elementRulesNb: 4,
firstLineRulesNb: 2,
firstLetterRulesNb: 1,
- selectionRulesNb: 0,
+ selectionRulesNb: 1,
afterRulesNb: 1,
beforeRulesNb: 2
}
@@ -167,7 +167,7 @@ function* testParagraph(inspector, view) {
elementRulesNb: 3,
firstLineRulesNb: 1,
firstLetterRulesNb: 1,
- selectionRulesNb: 1,
+ selectionRulesNb: 2,
beforeRulesNb: 0,
afterRulesNb: 0
});
@@ -217,7 +217,7 @@ function* assertPseudoElementRulesNumbers(selector, inspector, view, ruleNbs) {
firstLetterRules: elementStyle.rules.filter(rule =>
rule.pseudoElement === ":first-letter"),
selectionRules: elementStyle.rules.filter(rule =>
- rule.pseudoElement === ":-moz-selection"),
+ rule.pseudoElement === ":selection"),
beforeRules: elementStyle.rules.filter(rule =>
rule.pseudoElement === ":before"),
afterRules: elementStyle.rules.filter(rule =>
diff --git a/devtools/shared/css/generated/properties-db.js b/devtools/shared/css/generated/properties-db.js
index 316352771..01358a033 100644
--- a/devtools/shared/css/generated/properties-db.js
+++ b/devtools/shared/css/generated/properties-db.js
@@ -2872,6 +2872,7 @@ exports.CSS_PROPERTIES = {
"box-shadow",
"box-sizing",
"caption-side",
+ "caret-color",
"clear",
"clip",
"clip-path",
@@ -5277,6 +5278,28 @@ exports.CSS_PROPERTIES = {
"unset"
]
},
+ "caret-color": {
+ "isInherited": true,
+ "subproperties": [
+ "caret-color"
+ ],
+ "supports": [
+ 2
+ ],
+ "values": [
+ "COLOR",
+ "auto",
+ "currentColor",
+ "hsl",
+ "hsla",
+ "inherit",
+ "initial",
+ "rgb",
+ "rgba",
+ "transparent",
+ "unset"
+ ]
+ },
"clear": {
"isInherited": false,
"subproperties": [
@@ -9375,6 +9398,7 @@ exports.PSEUDO_ELEMENTS = [
":backdrop",
":first-letter",
":first-line",
+ ":selection",
":-moz-selection",
":-moz-focus-inner",
":-moz-focus-outer",
diff --git a/dom/base/ResizeObserverController.cpp b/dom/base/ResizeObserverController.cpp
index d4166155e..edf73fc73 100644
--- a/dom/base/ResizeObserverController.cpp
+++ b/dom/base/ResizeObserverController.cpp
@@ -16,7 +16,7 @@ namespace dom {
void
ResizeObserverNotificationHelper::WillRefresh(TimeStamp aTime)
{
- MOZ_ASSERT(mOwner, "Why is mOwner already dead when this RefreshObserver is still registered?");
+ MOZ_DIAGNOSTIC_ASSERT(mOwner, "RefreshObserver should have been de-registered on time, but isn't.");
if (mOwner) {
mOwner->Notify();
}
@@ -70,10 +70,8 @@ ResizeObserverNotificationHelper::Unregister()
}
nsRefreshDriver* refreshDriver = GetRefreshDriver();
- if (!refreshDriver) {
- // We can't access RefreshDriver now. Just abort the Unregister().
- return;
- }
+ MOZ_RELEASE_ASSERT(refreshDriver,
+ "We should not leave a dangling reference to the observer around");
refreshDriver->RemoveRefreshObserver(this, Flush_Display);
mRegistered = false;
@@ -82,9 +80,8 @@ ResizeObserverNotificationHelper::Unregister()
void
ResizeObserverNotificationHelper::Disconnect()
{
- Unregister();
- // Our owner is dying. Clear our pointer to it, in case we outlive it.
- mOwner = nullptr;
+ MOZ_RELEASE_ASSERT(!mRegistered, "How can we die when registered?");
+ MOZ_RELEASE_ASSERT(!mOwner, "Forgot to clear weak pointer?");
}
ResizeObserverNotificationHelper::~ResizeObserverNotificationHelper()
@@ -112,6 +109,10 @@ ResizeObserverController::AddResizeObserver(ResizeObserver* aObserver)
mResizeObservers.AppendElement(aObserver);
}
+void ResizeObserverController::DetachFromDocument() {
+ mResizeObserverNotificationHelper->Unregister();
+}
+
void
ResizeObserverController::Notify()
{
@@ -241,7 +242,10 @@ ResizeObserverController::GetShell() const
ResizeObserverController::~ResizeObserverController()
{
- mResizeObserverNotificationHelper->Disconnect();
+ MOZ_RELEASE_ASSERT(
+ !mResizeObserverNotificationHelper->IsRegistered(),
+ "Nothing else should keep a reference to our notification helper when we go away");
+ mResizeObserverNotificationHelper->DetachFromOwner();
}
} // namespace dom
diff --git a/dom/base/ResizeObserverController.h b/dom/base/ResizeObserverController.h
index a77511587..2ddfc958c 100644
--- a/dom/base/ResizeObserverController.h
+++ b/dom/base/ResizeObserverController.h
@@ -42,6 +42,10 @@ public:
void Disconnect();
+ bool IsRegistered() const { return mRegistered; }
+
+ void DetachFromOwner() { mOwner = nullptr; }
+
protected:
virtual ~ResizeObserverNotificationHelper();
@@ -69,6 +73,7 @@ public:
void Traverse(nsCycleCollectionTraversalCallback& aCb);
void Unlink();
+ void DetachFromDocument();
void AddResizeObserver(ResizeObserver* aObserver);
/*
diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp
index 0b07ef4ec..144f048eb 100644
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -3689,6 +3689,12 @@ nsDocument::DeleteShell()
// objects for @font-face rules that came from the style set.
RebuildUserFontSet();
+ if (mResizeObserverController) {
+ // If the shell is going away, we need to remove any links to this document
+ // from the observer.
+ mResizeObserverController->DetachFromDocument();
+ }
+
nsIPresShell* oldShell = mPresShell;
mPresShell = nullptr;
UpdateFrameRequestCallbackSchedulingState(oldShell);
diff --git a/dom/base/nsImageLoadingContent.cpp b/dom/base/nsImageLoadingContent.cpp
index 4aad55941..07bdb6967 100644
--- a/dom/base/nsImageLoadingContent.cpp
+++ b/dom/base/nsImageLoadingContent.cpp
@@ -933,8 +933,12 @@ nsImageLoadingContent::LoadImage(nsIURI* aNewURI,
MOZ_ASSERT(!req, "Shouldn't have non-null request here");
// If we don't have a current URI, we might as well store this URI so people
// know what we tried (and failed) to load.
- if (!mCurrentRequest)
+ if (!mCurrentRequest) {
mCurrentURI = aNewURI;
+ if (mImageBlockingStatus == nsIContentPolicy::ACCEPT) {
+ mImageBlockingStatus = nsIContentPolicy::REJECT_REQUEST;
+ }
+ }
FireEvent(NS_LITERAL_STRING("error"));
FireEvent(NS_LITERAL_STRING("loadend"));
diff --git a/dom/fetch/FetchDriver.cpp b/dom/fetch/FetchDriver.cpp
index fd1e99a2b..14c000121 100644
--- a/dom/fetch/FetchDriver.cpp
+++ b/dom/fetch/FetchDriver.cpp
@@ -709,10 +709,12 @@ FetchDriver::OnDataAvailable(nsIRequest* aRequest,
// about races.
if (mObserver) {
+ // Need to keep mObserver alive.
+ RefPtr<FetchDriverObserver> observer = mObserver;
if (NS_IsMainThread()) {
- mObserver->OnDataAvailable();
+ observer->OnDataAvailable();
} else {
- RefPtr<Runnable> runnable = new DataAvailableRunnable(mObserver);
+ RefPtr<Runnable> runnable = new DataAvailableRunnable(observer);
nsresult rv = NS_DispatchToMainThread(runnable);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
@@ -720,12 +722,15 @@ FetchDriver::OnDataAvailable(nsIRequest* aRequest,
}
}
- uint32_t aRead;
+ // Explicitly initialized to 0 because in some cases nsStringInputStream may
+ // not write to aRead.
+ uint32_t aRead = 0;
MOZ_ASSERT(mResponse);
MOZ_ASSERT(mPipeOutputStream);
// From "Main Fetch" step 17: SRI-part2.
- if (mResponse->Type() != ResponseType::Error &&
+ if (mResponse &&
+ mResponse->Type() != ResponseType::Error &&
!mRequest->GetIntegrity().IsEmpty()) {
MOZ_ASSERT(mSRIDataVerifier);
@@ -767,6 +772,17 @@ FetchDriver::OnDataAvailable(nsIRequest* aRequest,
nsresult rv = aInputStream->ReadSegments(NS_CopySegmentToStream,
mPipeOutputStream,
aCount, &aRead);
+
+ // If no data was read, it's possible the output stream is closed but the
+ // ReadSegments call followed its contract of returning NS_OK despite write
+ // errors. Unfortunately, nsIOutputStream has an ill-conceived contract when
+ // taken together with ReadSegments' contract, because the pipe will just
+ // NS_OK if we try and invoke its Write* functions ourselves with a 0 count.
+ // So we must just assume the pipe is broken.
+ if (aRead == 0 && aCount != 0) {
+ return NS_BASE_STREAM_CLOSED;
+ }
+
return rv;
}
diff --git a/dom/smil/nsSMILCSSProperty.cpp b/dom/smil/nsSMILCSSProperty.cpp
index 14e428c05..070f3489e 100644
--- a/dom/smil/nsSMILCSSProperty.cpp
+++ b/dom/smil/nsSMILCSSProperty.cpp
@@ -195,6 +195,7 @@ nsSMILCSSProperty::IsPropertyAnimatable(nsCSSPropertyID aPropID)
// writing-mode
switch (aPropID) {
+ case eCSSProperty_caret_color:
case eCSSProperty_clip:
case eCSSProperty_clip_rule:
case eCSSProperty_clip_path:
diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp
index cb70f8b1e..5296126ac 100644
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -1833,8 +1833,7 @@ nsIFrame::DisplayCaret(nsDisplayListBuilder* aBuilder,
nscolor
nsIFrame::GetCaretColorAt(int32_t aOffset)
{
- // Use text color.
- return StyleColor()->mColor;
+ return nsLayoutUtils::GetColor(this, eCSSProperty_caret_color);
}
bool
diff --git a/layout/generic/nsTextFrame.cpp b/layout/generic/nsTextFrame.cpp
index a47b87e38..c7b55961c 100644
--- a/layout/generic/nsTextFrame.cpp
+++ b/layout/generic/nsTextFrame.cpp
@@ -3949,11 +3949,18 @@ nsTextPaintStyle::InitSelectionColorsAndShadow()
if (selectionElement &&
selectionStatus == nsISelectionController::SELECTION_ON) {
RefPtr<nsStyleContext> sc = nullptr;
+ // Probe for both selection and -moz-selection
sc = mPresContext->StyleSet()->
ProbePseudoElementStyle(selectionElement,
- CSSPseudoElementType::mozSelection,
+ CSSPseudoElementType::selection,
mFrame->StyleContext());
- // Use -moz-selection pseudo class.
+ if (!sc) {
+ sc = mPresContext->StyleSet()->
+ ProbePseudoElementStyle(selectionElement,
+ CSSPseudoElementType::mozSelection,
+ mFrame->StyleContext());
+ }
+ // Use selection pseudo class.
if (sc) {
mSelectionBGColor =
sc->GetVisitedDependentColor(eCSSProperty_background_color);
diff --git a/layout/inspector/tests/test_getCSSPseudoElementNames.html b/layout/inspector/tests/test_getCSSPseudoElementNames.html
index cdb4572d4..8879f21dc 100644
--- a/layout/inspector/tests/test_getCSSPseudoElementNames.html
+++ b/layout/inspector/tests/test_getCSSPseudoElementNames.html
@@ -16,6 +16,7 @@
":first-letter",
":first-line",
":placeholder",
+ ":selection",
":-moz-color-swatch",
":-moz-focus-inner",
":-moz-focus-outer",
diff --git a/layout/reftests/image/reftest.list b/layout/reftests/image/reftest.list
index 1a610811d..0eddb61fc 100644
--- a/layout/reftests/image/reftest.list
+++ b/layout/reftests/image/reftest.list
@@ -126,3 +126,5 @@ fuzzy(1,1) == image-orientation-background.html?90&flip image-orientation-r
== image-resize-percent-height.html image-resize-ref.html
== image-resize-percent-width.html image-resize-ref.html
+
+== unknown-protocol.html unknown-protocol-ref.html
diff --git a/layout/reftests/image/unknown-protocol-ref.html b/layout/reftests/image/unknown-protocol-ref.html
new file mode 100644
index 000000000..b5bb326ee
--- /dev/null
+++ b/layout/reftests/image/unknown-protocol-ref.html
@@ -0,0 +1 @@
+<img src="mailto://foo">
diff --git a/layout/reftests/image/unknown-protocol.html b/layout/reftests/image/unknown-protocol.html
new file mode 100644
index 000000000..ef06881b7
--- /dev/null
+++ b/layout/reftests/image/unknown-protocol.html
@@ -0,0 +1 @@
+<img src="foobar://baz">
diff --git a/layout/style/StyleAnimationValue.cpp b/layout/style/StyleAnimationValue.cpp
index a0f52b4ea..d931961d4 100644
--- a/layout/style/StyleAnimationValue.cpp
+++ b/layout/style/StyleAnimationValue.cpp
@@ -4469,8 +4469,12 @@ StyleAnimationValue::ExtractComputedValue(nsCSSPropertyID aProperty,
StyleDataAtOffset<nscolor>(styleStruct, ssOffset));
return true;
case eStyleAnimType_ComplexColor: {
- aComputedValue.SetComplexColorValue(
- StyleDataAtOffset<StyleComplexColor>(styleStruct, ssOffset));
+ auto& color = StyleDataAtOffset<StyleComplexColor>(styleStruct, ssOffset);
+ if (color.mIsAuto) {
+ aComputedValue.SetAutoValue();
+ } else {
+ aComputedValue.SetComplexColorValue(color);
+ }
return true;
}
case eStyleAnimType_PaintServer: {
@@ -4783,7 +4787,9 @@ StyleAnimationValue::SetCurrentColorValue()
void
StyleAnimationValue::SetComplexColorValue(const StyleComplexColor& aColor)
{
- if (aColor.IsCurrentColor()) {
+ if (aColor.mIsAuto) {
+ SetAutoValue();
+ } else if (aColor.IsCurrentColor()) {
SetCurrentColorValue();
} else if (aColor.IsNumericColor()) {
SetColorValue(aColor.mColor);
diff --git a/layout/style/StyleComplexColor.h b/layout/style/StyleComplexColor.h
index 4acf90a56..6385b57a1 100644
--- a/layout/style/StyleComplexColor.h
+++ b/layout/style/StyleComplexColor.h
@@ -24,16 +24,29 @@ struct StyleComplexColor
{
nscolor mColor;
uint8_t mForegroundRatio;
-
- static StyleComplexColor FromColor(nscolor aColor) { return {aColor, 0}; }
- static StyleComplexColor CurrentColor() { return {NS_RGBA(0, 0, 0, 0), 255}; }
+ // Whether the complex color represents a computed-value time auto
+ // value. This is only a flag indicating that this value should not
+ // be interpolatable with other colors, while other fields still
+ // represents the actual used color of this value.
+ bool mIsAuto;
+
+ static StyleComplexColor FromColor(nscolor aColor) {
+ return {aColor, 0, false};
+ }
+ static StyleComplexColor CurrentColor() {
+ return {NS_RGBA(0, 0, 0, 0), 255, false};
+ }
+ static StyleComplexColor Auto() {
+ return {NS_RGBA(0, 0, 0, 0), 255, true};
+ }
bool IsNumericColor() const { return mForegroundRatio == 0; }
bool IsCurrentColor() const { return mForegroundRatio == 255; }
bool operator==(const StyleComplexColor& aOther) const {
return mForegroundRatio == aOther.mForegroundRatio &&
- (IsCurrentColor() || mColor == aOther.mColor);
+ (IsCurrentColor() || mColor == aOther.mColor) &&
+ mIsAuto == aOther.mIsAuto;
}
bool operator!=(const StyleComplexColor& aOther) const {
return !(*this == aOther);
diff --git a/layout/style/nsCSSPropList.h b/layout/style/nsCSSPropList.h
index 890019245..4f79db5a5 100644
--- a/layout/style/nsCSSPropList.h
+++ b/layout/style/nsCSSPropList.h
@@ -1394,6 +1394,17 @@ CSS_PROP_TABLEBORDER(
kCaptionSideKTable,
CSS_PROP_NO_OFFSET,
eStyleAnimType_Discrete)
+CSS_PROP_USERINTERFACE(
+ caret-color,
+ caret_color,
+ CaretColor,
+ CSS_PROPERTY_PARSE_VALUE |
+ CSS_PROPERTY_IGNORED_WHEN_COLORS_DISABLED,
+ "",
+ VARIANT_AUTO | VARIANT_HC,
+ nullptr,
+ offsetof(nsStyleUserInterface, mCaretColor),
+ eStyleAnimType_ComplexColor)
CSS_PROP_DISPLAY(
clear,
clear,
diff --git a/layout/style/nsCSSPseudoElementList.h b/layout/style/nsCSSPseudoElementList.h
index 552c76734..b8393d395 100644
--- a/layout/style/nsCSSPseudoElementList.h
+++ b/layout/style/nsCSSPseudoElementList.h
@@ -37,6 +37,9 @@ CSS_PSEUDO_ELEMENT(firstLine, ":first-line",
CSS_PSEUDO_ELEMENT_IS_CSS2 |
CSS_PSEUDO_ELEMENT_CONTAINS_ELEMENTS)
+CSS_PSEUDO_ELEMENT(selection, ":selection",
+ CSS_PSEUDO_ELEMENT_CONTAINS_ELEMENTS)
+// Keep the prefixed version for now.
CSS_PSEUDO_ELEMENT(mozSelection, ":-moz-selection",
CSS_PSEUDO_ELEMENT_CONTAINS_ELEMENTS)
diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp
index db39ef727..08c2846f7 100644
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -4147,6 +4147,14 @@ nsComputedDOMStyle::DoGetUnicodeBidi()
}
already_AddRefed<CSSValue>
+nsComputedDOMStyle::DoGetCaretColor()
+{
+ RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
+ SetValueFromComplexColor(val, StyleUserInterface()->mCaretColor);
+ return val.forget();
+}
+
+already_AddRefed<CSSValue>
nsComputedDOMStyle::DoGetCursor()
{
RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true);
diff --git a/layout/style/nsComputedDOMStyle.h b/layout/style/nsComputedDOMStyle.h
index e94d8dbf6..79c7ed519 100644
--- a/layout/style/nsComputedDOMStyle.h
+++ b/layout/style/nsComputedDOMStyle.h
@@ -482,6 +482,7 @@ private:
already_AddRefed<CSSValue> DoGetShapeOutside();
/* User interface properties */
+ already_AddRefed<CSSValue> DoGetCaretColor();
already_AddRefed<CSSValue> DoGetCursor();
already_AddRefed<CSSValue> DoGetForceBrokenImageIcon();
already_AddRefed<CSSValue> DoGetIMEMode();
diff --git a/layout/style/nsComputedDOMStylePropertyList.h b/layout/style/nsComputedDOMStylePropertyList.h
index 557281810..8d4d8e45e 100644
--- a/layout/style/nsComputedDOMStylePropertyList.h
+++ b/layout/style/nsComputedDOMStylePropertyList.h
@@ -101,6 +101,7 @@ COMPUTED_STYLE_PROP(box_decoration_break, BoxDecorationBreak)
COMPUTED_STYLE_PROP(box_shadow, BoxShadow)
COMPUTED_STYLE_PROP(box_sizing, BoxSizing)
COMPUTED_STYLE_PROP(caption_side, CaptionSide)
+COMPUTED_STYLE_PROP(caret_color, CaretColor)
COMPUTED_STYLE_PROP(clear, Clear)
COMPUTED_STYLE_PROP(clip, Clip)
COMPUTED_STYLE_PROP(color, Color)
diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp
index 036d97f86..1136edee2 100644
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -1152,13 +1152,16 @@ SetComplexColor(const nsCSSValue& aValue,
aResult = StyleComplexColor::CurrentColor();
} else if (unit == eCSSUnit_ComplexColor) {
aResult = aValue.GetStyleComplexColorValue();
+ } else if (unit == eCSSUnit_Auto) {
+ aResult = StyleComplexColor::Auto();
} else {
+ nscolor resultColor;
if (!SetColor(aValue, aParentColor.mColor, aPresContext,
- nullptr, aResult.mColor, aConditions)) {
+ nullptr, resultColor, aConditions)) {
MOZ_ASSERT_UNREACHABLE("Unknown color value");
return;
}
- aResult.mForegroundRatio = 0;
+ aResult = StyleComplexColor::FromColor(resultColor);
}
}
@@ -5139,6 +5142,13 @@ nsRuleNode::ComputeUserInterfaceData(void* aStartStruct,
{
COMPUTE_START_INHERITED(UserInterface, ui, parentUI)
+ auto setComplexColor = [&](const nsCSSValue* aValue,
+ StyleComplexColor nsStyleUserInterface::* aField) {
+ SetComplexColor<eUnsetInherit>(*aValue, parentUI->*aField,
+ StyleComplexColor::Auto(),
+ mPresContext, ui->*aField, conditions);
+ };
+
// cursor: enum, url, inherit
const nsCSSValue* cursorValue = aRuleData->ValueForCursor();
nsCSSUnit cursorUnit = cursorValue->GetUnit();
@@ -5210,6 +5220,10 @@ nsRuleNode::ComputeUserInterfaceData(void* aStartStruct,
parentUI->mPointerEvents,
NS_STYLE_POINTER_EVENTS_AUTO);
+ // caret-color: auto, color, inherit
+ setComplexColor(aRuleData->ValueForCaretColor(),
+ &nsStyleUserInterface::mCaretColor);
+
COMPUTE_END_INHERITED(UserInterface, ui)
}
diff --git a/layout/style/nsStyleContext.cpp b/layout/style/nsStyleContext.cpp
index 4b1a14897..38b422bd7 100644
--- a/layout/style/nsStyleContext.cpp
+++ b/layout/style/nsStyleContext.cpp
@@ -1255,6 +1255,17 @@ nsStyleContext::CalcStyleDifferenceInternal(StyleContextLike* aNewContext,
}
}
+ // NB: Calling Peek on |this|, not |thisVis| (see above).
+ if (!change && PeekStyleUserInterface()) {
+ const nsStyleUserInterface *thisVisUserInterface = thisVis->StyleUserInterface();
+ const nsStyleUserInterface *otherVisUserInterface = otherVis->StyleUserInterface();
+ if (thisVisUserInterface->mCaretColor !=
+ otherVisUserInterface->mCaretColor) {
+ change = true;
+ }
+ }
+
+
if (change) {
hint |= nsChangeHint_RepaintFrame;
}
@@ -1487,6 +1498,9 @@ ExtractColor(nsCSSPropertyID aProperty,
case StyleAnimationValue::eUnit_ComplexColor:
return Some(aStyleContext->StyleColor()->
CalcComplexColor(val.GetStyleComplexColorValue()));
+ case StyleAnimationValue::eUnit_Auto:
+ return Some(aStyleContext->StyleColor()->
+ CalcComplexColor(StyleComplexColor::Auto()));
default:
return Nothing();
}
@@ -1508,7 +1522,8 @@ static const ColorIndexSet gVisitedIndices[2] = { { 0, 0 }, { 1, 0 } };
nscolor
nsStyleContext::GetVisitedDependentColor(nsCSSPropertyID aProperty)
{
- NS_ASSERTION(aProperty == eCSSProperty_color ||
+ NS_ASSERTION(aProperty == eCSSProperty_caret_color ||
+ aProperty == eCSSProperty_color ||
aProperty == eCSSProperty_background_color ||
aProperty == eCSSProperty_border_top_color ||
aProperty == eCSSProperty_border_right_color ||
diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp
index 3b19a4418..4c610cf08 100644
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -4024,6 +4024,7 @@ nsStyleUserInterface::nsStyleUserInterface(StyleStructContext aContext)
, mUserFocus(StyleUserFocus::None)
, mPointerEvents(NS_STYLE_POINTER_EVENTS_AUTO)
, mCursor(NS_STYLE_CURSOR_AUTO)
+ , mCaretColor(StyleComplexColor::Auto())
{
MOZ_COUNT_CTOR(nsStyleUserInterface);
}
@@ -4035,6 +4036,7 @@ nsStyleUserInterface::nsStyleUserInterface(const nsStyleUserInterface& aSource)
, mPointerEvents(aSource.mPointerEvents)
, mCursor(aSource.mCursor)
, mCursorImages(aSource.mCursorImages)
+ , mCaretColor(aSource.mCaretColor)
{
MOZ_COUNT_CTOR(nsStyleUserInterface);
}
@@ -4083,6 +4085,10 @@ nsStyleUserInterface::CalcDifference(const nsStyleUserInterface& aNewData) const
hint |= nsChangeHint_NeutralChange;
}
+ if (mCaretColor != aNewData.mCaretColor) {
+ hint |= nsChangeHint_RepaintFrame;
+ }
+
return hint;
}
diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h
index cca7bb8d4..97724571d 100644
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -3417,6 +3417,7 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleUserInterface
uint8_t mCursor; // [inherited] See nsStyleConsts.h
nsTArray<nsCursorImage> mCursorImages; // [inherited] images and coords
+ mozilla::StyleComplexColor mCaretColor; // [inherited]
inline uint8_t GetEffectivePointerEvents(nsIFrame* aFrame) const;
};
diff --git a/layout/style/test/property_database.js b/layout/style/test/property_database.js
index bc4383630..a7014c043 100644
--- a/layout/style/test/property_database.js
+++ b/layout/style/test/property_database.js
@@ -2837,6 +2837,18 @@ var gCSSProperties = {
other_values: [ "bottom", "left", "right", "top-outside", "bottom-outside" ],
invalid_values: []
},
+ "caret-color": {
+ domProp: "caretColor",
+ inherited: true,
+ type: CSS_TYPE_LONGHAND,
+ prerequisites: { "color": "black" },
+ // Though "auto" is an independent computed-value time keyword value,
+ // it is not distinguishable from currentcolor because getComputedStyle
+ // always returns used value for <color>.
+ initial_values: [ "auto", "currentcolor", "black", "rgb(0,0,0)" ],
+ other_values: [ "green", "transparent", "rgba(128,128,128,.5)", "#123" ],
+ invalid_values: [ "#0", "#00", "#00000", "cc00ff" ]
+ },
"clear": {
domProp: "clear",
inherited: false,
diff --git a/layout/style/test/test_transitions_per_property.html b/layout/style/test/test_transitions_per_property.html
index 29e2ae24c..f188f4f6f 100644
--- a/layout/style/test/test_transitions_per_property.html
+++ b/layout/style/test/test_transitions_per_property.html
@@ -1373,6 +1373,21 @@ function test_true_currentcolor_transition(prop, get_color=(x => x), is_shorthan
div.style.removeProperty("color");
}
+function test_auto_color_transition(prop, get_color=(x => x), is_shorthand=false) {
+ const msg_prefix = `color-valued property ${prop}: `;
+ const test_color = "rgb(51, 102, 153)";
+ div.style.setProperty("transition-property", "none", "");
+ div.style.setProperty(prop, "auto", "");
+ let used_value_of_auto = get_color(cs.getPropertyValue(prop));
+ isnot(used_value_of_auto, test_color,
+ msg_prefix + "ensure used auto value is different than our test color");
+
+ div.style.setProperty("transition-property", prop, "");
+ div.style.setProperty(prop, test_color, "");
+ is(get_color(cs.getPropertyValue(prop)), test_color,
+ msg_prefix + "not interpolatable between auto and rgb color");
+}
+
function get_color_from_shorthand_value(value) {
var m = value.match(/rgba?\([^, ]*, [^, ]*, [^, ]*(?:, [^, ]*)?\)/);
isnot(m, null, "shorthand property value should contain color");
diff --git a/layout/tables/nsTableFrame.cpp b/layout/tables/nsTableFrame.cpp
index 59a6d0f1a..eb8efb0ec 100644
--- a/layout/tables/nsTableFrame.cpp
+++ b/layout/tables/nsTableFrame.cpp
@@ -104,6 +104,14 @@ struct TableReflowInput {
availSize.BSize(wm) = std::max(0, availSize.BSize(wm));
}
}
+
+ void ReduceAvailableBSizeBy(WritingMode aWM, nscoord aAmount) {
+ if (availSize.BSize(aWM) == NS_UNCONSTRAINEDSIZE) {
+ return;
+ }
+ availSize.BSize(aWM) -= aAmount;
+ availSize.BSize(aWM) = std::max(0, availSize.BSize(aWM));
+ }
};
} // namespace mozilla
@@ -2682,9 +2690,7 @@ nsTableFrame::PlaceChild(TableReflowInput& aReflowInput,
aReflowInput.bCoord += aKidDesiredSize.BSize(wm);
// If our bsize is constrained, then update the available bsize
- if (NS_UNCONSTRAINEDSIZE != aReflowInput.availSize.BSize(wm)) {
- aReflowInput.availSize.BSize(wm) -= aKidDesiredSize.BSize(wm);
- }
+ aReflowInput.ReduceAvailableBSizeBy(wm, aKidDesiredSize.BSize(wm));
}
void
@@ -2928,17 +2934,28 @@ nsTableFrame::ReflowChildren(TableReflowInput& aReflowInput,
// using the footer's prev-in-flow's height instead of reflowing it again,
// but there's no real need.
if (isPaginated) {
+ bool reorder = false;
if (thead && !GetPrevInFlow()) {
+ if (thead->GetNextInFlow()) {
+ reorder = true;
+ }
nscoord desiredHeight;
nsresult rv = SetupHeaderFooterChild(aReflowInput, thead, &desiredHeight);
if (NS_FAILED(rv))
return;
}
if (tfoot) {
+ if (tfoot->GetNextInFlow()) {
+ reorder = true;
+ }
nsresult rv = SetupHeaderFooterChild(aReflowInput, tfoot, &footerHeight);
if (NS_FAILED(rv))
return;
}
+ if (reorder) {
+ // Reorder row groups, because the reflow may have changed what's next-in-flow.
+ OrderRowGroups(rowGroups, &thead, &tfoot);
+ }
}
// if the child is a tbody in paginated mode reduce the height by a repeated footer
bool allowRepeatedFooter = false;
@@ -3004,14 +3021,13 @@ nsTableFrame::ReflowChildren(TableReflowInput& aReflowInput,
kidReflowInput.mFlags.mIsTopOfPage = false;
}
aReflowInput.bCoord += cellSpacingB;
- if (NS_UNCONSTRAINEDSIZE != aReflowInput.availSize.BSize(wm)) {
- aReflowInput.availSize.BSize(wm) -= cellSpacingB;
- }
+ aReflowInput.ReduceAvailableBSizeBy(wm, cellSpacingB);
// record the presence of a next in flow, it might get destroyed so we
// need to reorder the row group array
bool reorder = false;
- if (kidFrame->GetNextInFlow())
+ if (kidFrame->GetNextInFlow()) {
reorder = true;
+ }
LogicalPoint kidPosition(wm, aReflowInput.iCoord, aReflowInput.bCoord);
ReflowChild(kidFrame, presContext, desiredSize, kidReflowInput,
@@ -3019,7 +3035,7 @@ nsTableFrame::ReflowChildren(TableReflowInput& aReflowInput,
kidReflowInput.ApplyRelativePositioning(&kidPosition, containerSize);
if (reorder) {
- // reorder row groups the reflow may have changed the nextinflows
+ // Reorder row groups, because the reflow may have changed what's next-in-flow.
OrderRowGroups(rowGroups, &thead, &tfoot);
childX = rowGroups.IndexOf(kidFrame);
if (childX == RowGroupArray::NoIndex) {
@@ -3171,9 +3187,7 @@ nsTableFrame::ReflowChildren(TableReflowInput& aReflowInput,
aReflowInput.bCoord += kidRect.BSize(wm);
// If our bsize is constrained then update the available bsize.
- if (NS_UNCONSTRAINEDSIZE != aReflowInput.availSize.BSize(wm)) {
- aReflowInput.availSize.BSize(wm) -= cellSpacingB + kidRect.BSize(wm);
- }
+ aReflowInput.ReduceAvailableBSizeBy(wm, cellSpacingB + kidRect.BSize(wm));
}
}
diff --git a/netwerk/base/nsIncrementalStreamLoader.cpp b/netwerk/base/nsIncrementalStreamLoader.cpp
index a7298be3f..8890333f8 100644
--- a/netwerk/base/nsIncrementalStreamLoader.cpp
+++ b/netwerk/base/nsIncrementalStreamLoader.cpp
@@ -11,10 +11,7 @@
#include <limits>
-nsIncrementalStreamLoader::nsIncrementalStreamLoader()
- : mData(), mBytesConsumed(0)
-{
-}
+nsIncrementalStreamLoader::nsIncrementalStreamLoader() = default;
nsIncrementalStreamLoader::~nsIncrementalStreamLoader()
{
@@ -49,7 +46,7 @@ NS_IMPL_ISUPPORTS(nsIncrementalStreamLoader, nsIIncrementalStreamLoader,
NS_IMETHODIMP
nsIncrementalStreamLoader::GetNumBytesRead(uint32_t* aNumBytes)
{
- *aNumBytes = mBytesConsumed + mData.length();
+ *aNumBytes = mBytesRead;
return NS_OK;
}
@@ -180,7 +177,6 @@ nsIncrementalStreamLoader::WriteSegmentFun(nsIInputStream *inStr,
}
}
- self->mBytesConsumed += consumedCount;
*writeCount = count;
return NS_OK;
@@ -198,6 +194,8 @@ nsIncrementalStreamLoader::OnDataAvailable(nsIRequest* request, nsISupports *ctx
uint32_t countRead;
nsresult rv = inStr->ReadSegments(WriteSegmentFun, this, count, &countRead);
mRequest = nullptr;
+ NS_ENSURE_SUCCESS(rv, rv);
+ mBytesRead += countRead;
return rv;
}
diff --git a/netwerk/base/nsIncrementalStreamLoader.h b/netwerk/base/nsIncrementalStreamLoader.h
index f04d4a958..0e2b532e6 100644
--- a/netwerk/base/nsIncrementalStreamLoader.h
+++ b/netwerk/base/nsIncrementalStreamLoader.h
@@ -47,8 +47,9 @@ protected:
// available.
mozilla::Vector<uint8_t, 0> mData;
- // Number of consumed bytes from the mData.
- size_t mBytesConsumed;
+ // Number of bytes read, which may differ from the number of bytes in mData,
+ // since we incrementally remove from there.
+ mozilla::Atomic<uint32_t, mozilla::Relaxed> mBytesRead;
};
#endif // nsIncrementalStreamLoader_h__
diff --git a/netwerk/base/nsStreamLoader.cpp b/netwerk/base/nsStreamLoader.cpp
index a73b038a7..9990d1882 100644
--- a/netwerk/base/nsStreamLoader.cpp
+++ b/netwerk/base/nsStreamLoader.cpp
@@ -54,7 +54,7 @@ NS_IMPL_ISUPPORTS(nsStreamLoader, nsIStreamLoader,
NS_IMETHODIMP
nsStreamLoader::GetNumBytesRead(uint32_t* aNumBytes)
{
- *aNumBytes = mData.length();
+ *aNumBytes = mBytesRead;
return NS_OK;
}
@@ -150,7 +150,10 @@ nsStreamLoader::OnDataAvailable(nsIRequest* request, nsISupports *ctxt,
uint64_t sourceOffset, uint32_t count)
{
uint32_t countRead;
- return inStr->ReadSegments(WriteSegmentFun, this, count, &countRead);
+ nsresult rv = inStr->ReadSegments(WriteSegmentFun, this, count, &countRead);
+ NS_ENSURE_SUCCESS(rv, rv);
+ mBytesRead += countRead;
+ return NS_OK;
}
void
diff --git a/netwerk/base/nsStreamLoader.h b/netwerk/base/nsStreamLoader.h
index 671fc441f..b611a1aed 100644
--- a/netwerk/base/nsStreamLoader.h
+++ b/netwerk/base/nsStreamLoader.h
@@ -47,6 +47,8 @@ protected:
nsCOMPtr<nsIRequest> mRequest;
nsCOMPtr<nsIRequestObserver> mRequestObserver;
+ mozilla::Atomic<uint32_t, mozilla::Relaxed> mBytesRead;
+
// Buffer to accumulate incoming data. We preallocate if contentSize is
// available.
mozilla::Vector<uint8_t, 0> mData;