--- a/devtools/shared/css/generated/properties-db.js
+++ b/devtools/shared/css/generated/properties-db.js
@@ -2852,16 +2852,17 @@ exports.CSS_PROPERTIES = {
"-moz-box-direction",
"-moz-box-flex",
"-moz-box-ordinal-group",
"-moz-box-orient",
"-moz-box-pack",
"box-shadow",
"box-sizing",
"caption-side",
+ "caret-color",
"clear",
"clip",
"clip-path",
"clip-rule",
"color",
"color-adjust",
"color-interpolation",
"color-interpolation-filters",
@@ -5256,16 +5257,38 @@ exports.CSS_PROPERTIES = {
"initial",
"left",
"right",
"top",
"top-outside",
"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": [
"clear"
],
"supports": [],
"values": [
"both",
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -1876,18 +1876,17 @@ nsIFrame::DisplayCaret(nsDisplayListBuil
return;
aList->AppendNewToTop(new (aBuilder) nsDisplayCaret(aBuilder, this));
}
nscolor
nsIFrame::GetCaretColorAt(int32_t aOffset)
{
- // Use text color.
- return StyleColor()->mColor;
+ return StyleColor()->CalcComplexColor(StyleUserInterface()->mCaretColor);
}
bool
nsFrame::DisplayBackgroundUnconditional(nsDisplayListBuilder* aBuilder,
const nsDisplayListSet& aLists,
bool aForceBackground)
{
// Here we don't try to detect background propagation. Frames that might
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-ui/caret-color-01-ref.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<style>
+@font-face {
+ font-family: Ahem;
+ src: url(../fonts/Ahem.ttf);
+}
+div {
+ font: 16px/1 Ahem;
+ width: 1em;
+ background: green;
+}
+</style>
+<div><span></span></div>
+<script>
+let $div = document.querySelector('div');
+let $span = document.querySelector('span');
+$div.style.height = $span.getBoundingClientRect().height + 'px';
+</script>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-ui/caret-color-01.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<style>
+@font-face {
+ font-family: Ahem;
+ src: url(../fonts/Ahem.ttf);
+}
+textarea {
+ caret-color: green;
+ font: 16px/1 Ahem;
+ outline: none;
+ border: 0 none;
+ resize: none;
+ padding: 0;
+ margin: 0;
+}
+</style>
+<textarea autofocus></textarea>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-ui/reftest.list
@@ -0,0 +1,1 @@
+pref(ui.caretWidth,16) needs-focus == caret-color-01.html caret-color-01-ref.html
--- a/layout/reftests/reftest.list
+++ b/layout/reftests/reftest.list
@@ -125,16 +125,19 @@ include text-overflow/reftest.list
include css-selectors/reftest.list
# css sizing
include css-sizing/reftest.list
# css transitions
include css-transitions/reftest.list
+# css ui
+include css-ui/reftest.list
+
# css :-moz-ui-invalid
include css-ui-invalid/reftest.list
# css :-moz-ui-valid
include css-ui-valid/reftest.list
# css values and units
include css-valuesandunits/reftest.list
--- a/layout/style/nsCSSPropList.h
+++ b/layout/style/nsCSSPropList.h
@@ -1376,16 +1376,27 @@ CSS_PROP_TABLEBORDER(
caption_side,
CaptionSide,
CSS_PROPERTY_PARSE_VALUE,
"",
VARIANT_HK,
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,
Clear,
CSS_PROPERTY_PARSE_VALUE,
"",
VARIANT_HK,
kClearKTable,
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -4133,16 +4133,24 @@ nsComputedDOMStyle::DoGetUnicodeBidi()
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
val->SetIdent(
nsCSSProps::ValueToKeywordEnum(StyleTextReset()->mUnicodeBidi,
nsCSSProps::kUnicodeBidiKTable));
return val.forget();
}
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);
const nsStyleUserInterface *ui = StyleUserInterface();
for (const nsCursorImage& item : ui->mCursorImages) {
RefPtr<nsDOMCSSValueList> itemList = GetROCSSValueList(false);
--- a/layout/style/nsComputedDOMStyle.h
+++ b/layout/style/nsComputedDOMStyle.h
@@ -482,16 +482,17 @@ private:
already_AddRefed<CSSValue> DoGetScrollSnapTypeY();
already_AddRefed<CSSValue> DoGetScrollSnapPointsX();
already_AddRefed<CSSValue> DoGetScrollSnapPointsY();
already_AddRefed<CSSValue> DoGetScrollSnapDestination();
already_AddRefed<CSSValue> DoGetScrollSnapCoordinate();
already_AddRefed<CSSValue> DoGetShapeOutside();
/* User interface properties */
+ already_AddRefed<CSSValue> DoGetCaretColor();
already_AddRefed<CSSValue> DoGetCursor();
already_AddRefed<CSSValue> DoGetForceBrokenImageIcon();
already_AddRefed<CSSValue> DoGetIMEMode();
already_AddRefed<CSSValue> DoGetUserFocus();
already_AddRefed<CSSValue> DoGetUserInput();
already_AddRefed<CSSValue> DoGetUserModify();
already_AddRefed<CSSValue> DoGetUserSelect();
already_AddRefed<CSSValue> DoGetWindowDragging();
--- a/layout/style/nsComputedDOMStylePropertyList.h
+++ b/layout/style/nsComputedDOMStylePropertyList.h
@@ -96,16 +96,17 @@ COMPUTED_STYLE_PROP(border_top_right_rad
COMPUTED_STYLE_PROP(border_top_style, BorderTopStyle)
COMPUTED_STYLE_PROP(border_top_width, BorderTopWidth)
//// COMPUTED_STYLE_PROP(border_width, BorderWidth)
COMPUTED_STYLE_PROP(bottom, Bottom)
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)
COMPUTED_STYLE_PROP(color_adjust, ColorAdjust)
COMPUTED_STYLE_PROP(column_count, ColumnCount)
COMPUTED_STYLE_PROP(column_fill, ColumnFill)
COMPUTED_STYLE_PROP(column_gap, ColumnGap)
//// COMPUTED_STYLE_PROP(column_rule, ColumnRule)
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -1131,16 +1131,18 @@ SetComplexColor(const nsCSSValue& aValue
(UnsetTo == eUnsetInherit && unit == eCSSUnit_Unset)) {
aConditions.SetUncacheable();
aResult = aParentColor;
} else if (unit == eCSSUnit_EnumColor &&
aValue.GetIntValue() == NS_COLOR_CURRENTCOLOR) {
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, resultColor, aConditions)) {
MOZ_ASSERT_UNREACHABLE("Unknown color value");
return;
}
aResult = StyleComplexColor::FromColor(resultColor);
@@ -5283,16 +5285,24 @@ nsRuleNode::ComputeUserInterfaceData(voi
// pointer-events: enum, inherit, initial
SetValue(*aRuleData->ValueForPointerEvents(), ui->mPointerEvents,
conditions,
SETVAL_ENUMERATED | SETVAL_UNSET_INHERIT,
parentUI->mPointerEvents,
NS_STYLE_POINTER_EVENTS_AUTO);
+ // caret-color: auto, color, inherit
+ const nsCSSValue* caretColorValue = aRuleData->ValueForCaretColor();
+ SetComplexColor<eUnsetInherit>(*caretColorValue,
+ parentUI->mCaretColor,
+ StyleComplexColor::Auto(),
+ mPresContext,
+ ui->mCaretColor, conditions);
+
COMPUTE_END_INHERITED(UserInterface, ui)
}
const void*
nsRuleNode::ComputeUIResetData(void* aStartStruct,
const nsRuleData* aRuleData,
nsStyleContext* aContext,
nsRuleNode* aHighestNode,
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -3968,27 +3968,29 @@ nsCursorImage::operator==(const nsCursor
}
nsStyleUserInterface::nsStyleUserInterface(StyleStructContext aContext)
: mUserInput(StyleUserInput::Auto)
, mUserModify(StyleUserModify::ReadOnly)
, mUserFocus(StyleUserFocus::None)
, mPointerEvents(NS_STYLE_POINTER_EVENTS_AUTO)
, mCursor(NS_STYLE_CURSOR_AUTO)
+ , mCaretColor(StyleComplexColor::Auto())
{
MOZ_COUNT_CTOR(nsStyleUserInterface);
}
nsStyleUserInterface::nsStyleUserInterface(const nsStyleUserInterface& aSource)
: mUserInput(aSource.mUserInput)
, mUserModify(aSource.mUserModify)
, mUserFocus(aSource.mUserFocus)
, mPointerEvents(aSource.mPointerEvents)
, mCursor(aSource.mCursor)
, mCursorImages(aSource.mCursorImages)
+ , mCaretColor(aSource.mCaretColor)
{
MOZ_COUNT_CTOR(nsStyleUserInterface);
}
nsStyleUserInterface::~nsStyleUserInterface()
{
MOZ_COUNT_DTOR(nsStyleUserInterface);
}
@@ -4040,16 +4042,20 @@ nsStyleUserInterface::CalcDifference(con
hint |= nsChangeHint_NeutralChange;
}
}
if (mUserFocus != aNewData.mUserFocus) {
hint |= nsChangeHint_NeutralChange;
}
+ if (mCaretColor != aNewData.mCaretColor) {
+ hint |= nsChangeHint_RepaintFrame;
+ }
+
return hint;
}
//-----------------------
// nsStyleUIReset
//
nsStyleUIReset::nsStyleUIReset(StyleStructContext aContext)
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -3390,16 +3390,17 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsSt
mozilla::StyleUserInput mUserInput; // [inherited]
mozilla::StyleUserModify mUserModify; // [inherited] (modify-content)
mozilla::StyleUserFocus mUserFocus; // [inherited] (auto-select)
uint8_t mPointerEvents; // [inherited] see nsStyleConsts.h
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;
};
struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleXUL
{
explicit nsStyleXUL(StyleStructContext aContext);
nsStyleXUL(const nsStyleXUL& aSource);
--- a/layout/style/test/property_database.js
+++ b/layout/style/test/property_database.js
@@ -2831,16 +2831,28 @@ var gCSSProperties = {
"caption-side": {
domProp: "captionSide",
inherited: true,
type: CSS_TYPE_LONGHAND,
initial_values: [ "top" ],
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,
type: CSS_TYPE_LONGHAND,
initial_values: [ "none" ],
other_values: [ "left", "right", "both" ],
invalid_values: []
},
--- a/layout/style/test/test_transitions_per_property.html
+++ b/layout/style/test/test_transitions_per_property.html
@@ -124,16 +124,19 @@ var supported_properties = {
test_length_pair_transition_clamped ],
"border-top-color": [ test_color_transition,
test_true_currentcolor_transition ],
"border-top-width": [ test_length_transition,
test_length_clamped ],
"bottom": [ test_length_transition, test_percent_transition,
test_length_percent_calc_transition,
test_length_unclamped, test_percent_unclamped ],
+ "caret-color": [ test_color_transition,
+ test_true_currentcolor_transition,
+ test_auto_color_transition ],
"clip": [ test_rect_transition ],
"clip-path": [ test_clip_path_transition ],
"color": [ test_color_transition,
test_currentcolor_transition ],
"fill": [ test_color_transition,
test_currentcolor_transition ],
"fill-opacity" : [ test_float_zeroToOne_transition,
// opacity is clamped in computed style
--- a/layout/tools/reftest/reftest-preferences.js
+++ b/layout/tools/reftest/reftest-preferences.js
@@ -2,16 +2,17 @@
// content XBL bindings, so we set this pref to true. In reftests, we're
// more interested in testing the behavior of XBL as it works in chrome,
// so we want this pref to be false.
user_pref("dom.use_xbl_scopes_for_remote_xul", false);
user_pref("gfx.color_management.mode", 2);
user_pref("gfx.color_management.force_srgb", true);
user_pref("browser.dom.window.dump.enabled", true);
user_pref("ui.caretBlinkTime", -1);
+user_pref("ui.caretWidth", 1);
user_pref("dom.send_after_paint_to_content", true);
// no slow script dialogs
user_pref("dom.max_script_run_time", 0);
user_pref("dom.max_chrome_script_run_time", 0);
user_pref("hangmonitor.timeout", 0);
// Ensure autoplay is enabled for all platforms.
user_pref("media.autoplay.enabled", true);
// Disable updates