Bug 1867939, part 4: Implemented the ::target-text CSS Pseudo Element. r=emilio,devtools-reviewers,nchevobbe
This patch implements the `::target-text` pseudo element. Similarly to the Custom Highlight API, this is done implementing a new Selection type. Differential Revision: https://phabricator.services.mozilla.com/D195687
This commit is contained in:
@@ -704,6 +704,7 @@ class PageStyleActor extends Actor {
|
|||||||
case "::first-line":
|
case "::first-line":
|
||||||
case "::selection":
|
case "::selection":
|
||||||
case "::highlight":
|
case "::highlight":
|
||||||
|
case "::target-text":
|
||||||
return true;
|
return true;
|
||||||
case "::marker":
|
case "::marker":
|
||||||
return this._nodeIsListItem(node);
|
return this._nodeIsListItem(node);
|
||||||
|
|||||||
@@ -41,11 +41,12 @@ interface nsISelectionController : nsISelectionDisplay
|
|||||||
const short SELECTION_FIND = 8;
|
const short SELECTION_FIND = 8;
|
||||||
const short SELECTION_URLSECONDARY = 9;
|
const short SELECTION_URLSECONDARY = 9;
|
||||||
const short SELECTION_URLSTRIKEOUT = 10;
|
const short SELECTION_URLSTRIKEOUT = 10;
|
||||||
|
const short SELECTION_TARGET_TEXT = 11;
|
||||||
// Custom Highlight API
|
// Custom Highlight API
|
||||||
// (see https://drafts.csswg.org/css-highlight-api-1/#enumdef-highlighttype)
|
// (see https://drafts.csswg.org/css-highlight-api-1/#enumdef-highlighttype)
|
||||||
const short SELECTION_HIGHLIGHT = 11;
|
const short SELECTION_HIGHLIGHT = 12;
|
||||||
// End of RawSelectionType values.
|
// End of RawSelectionType values.
|
||||||
const short NUM_SELECTIONTYPES = 12;
|
const short NUM_SELECTIONTYPES = 13;
|
||||||
|
|
||||||
// SelectionRegion values:
|
// SelectionRegion values:
|
||||||
const short SELECTION_ANCHOR_REGION = 0;
|
const short SELECTION_ANCHOR_REGION = 0;
|
||||||
@@ -311,6 +312,7 @@ enum class SelectionType : RawSelectionType
|
|||||||
eFind = nsISelectionController::SELECTION_FIND,
|
eFind = nsISelectionController::SELECTION_FIND,
|
||||||
eURLSecondary = nsISelectionController::SELECTION_URLSECONDARY,
|
eURLSecondary = nsISelectionController::SELECTION_URLSECONDARY,
|
||||||
eURLStrikeout = nsISelectionController::SELECTION_URLSTRIKEOUT,
|
eURLStrikeout = nsISelectionController::SELECTION_URLSTRIKEOUT,
|
||||||
|
eTargetText = nsISelectionController::SELECTION_TARGET_TEXT,
|
||||||
eHighlight = nsISelectionController::SELECTION_HIGHLIGHT,
|
eHighlight = nsISelectionController::SELECTION_HIGHLIGHT,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -327,6 +329,7 @@ static const SelectionType kPresentSelectionTypes[] = {
|
|||||||
SelectionType::eFind,
|
SelectionType::eFind,
|
||||||
SelectionType::eURLSecondary,
|
SelectionType::eURLSecondary,
|
||||||
SelectionType::eURLStrikeout,
|
SelectionType::eURLStrikeout,
|
||||||
|
SelectionType::eTargetText,
|
||||||
SelectionType::eHighlight,
|
SelectionType::eHighlight,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -156,9 +156,10 @@ PeekOffsetStruct::PeekOffsetStruct(nsSelectionAmount aAmount,
|
|||||||
|
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
||||||
// Array which contains index of each SelecionType in Selection::mDOMSelections.
|
// Array which contains index of each SelectionType in
|
||||||
// For avoiding using if nor switch to retrieve the index, this needs to have
|
// Selection::mDOMSelections. For avoiding using if nor switch to retrieve the
|
||||||
// -1 for SelectionTypes which won't be created its Selection instance.
|
// index, this needs to have -1 for SelectionTypes which won't be created its
|
||||||
|
// Selection instance.
|
||||||
static const int8_t kIndexOfSelections[] = {
|
static const int8_t kIndexOfSelections[] = {
|
||||||
-1, // SelectionType::eInvalid
|
-1, // SelectionType::eInvalid
|
||||||
-1, // SelectionType::eNone
|
-1, // SelectionType::eNone
|
||||||
@@ -172,6 +173,7 @@ static const int8_t kIndexOfSelections[] = {
|
|||||||
7, // SelectionType::eFind
|
7, // SelectionType::eFind
|
||||||
8, // SelectionType::eURLSecondary
|
8, // SelectionType::eURLSecondary
|
||||||
9, // SelectionType::eURLStrikeout
|
9, // SelectionType::eURLStrikeout
|
||||||
|
10, // SelectionType::eTargetText
|
||||||
-1, // SelectionType::eHighlight
|
-1, // SelectionType::eHighlight
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -2402,6 +2402,15 @@ already_AddRefed<ComputedStyle> nsIFrame::ComputeHighlightSelectionStyle(
|
|||||||
*element, PseudoStyleType::highlight, aHighlightName, Style());
|
*element, PseudoStyleType::highlight, aHighlightName, Style());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
already_AddRefed<ComputedStyle> nsIFrame::ComputeTargetTextStyle() const {
|
||||||
|
const Element* element = FindElementAncestorForMozSelection(GetContent());
|
||||||
|
if (!element) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return PresContext()->StyleSet()->ProbePseudoElementStyle(
|
||||||
|
*element, PseudoStyleType::targetText, nullptr, Style());
|
||||||
|
}
|
||||||
|
|
||||||
template <typename SizeOrMaxSize>
|
template <typename SizeOrMaxSize>
|
||||||
static inline bool IsIntrinsicKeyword(const SizeOrMaxSize& aSize) {
|
static inline bool IsIntrinsicKeyword(const SizeOrMaxSize& aSize) {
|
||||||
// All keywords other than auto/none/-moz-available depend on intrinsic sizes.
|
// All keywords other than auto/none/-moz-available depend on intrinsic sizes.
|
||||||
|
|||||||
@@ -937,6 +937,8 @@ class nsIFrame : public nsQueryFrame {
|
|||||||
already_AddRefed<ComputedStyle> ComputeHighlightSelectionStyle(
|
already_AddRefed<ComputedStyle> ComputeHighlightSelectionStyle(
|
||||||
nsAtom* aHighlightName);
|
nsAtom* aHighlightName);
|
||||||
|
|
||||||
|
already_AddRefed<ComputedStyle> ComputeTargetTextStyle() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Accessor functions for geometric parent.
|
* Accessor functions for geometric parent.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -5676,6 +5676,10 @@ bool nsTextFrame::GetSelectionTextColors(SelectionType aSelectionType,
|
|||||||
aHighlightName, aBackground);
|
aHighlightName, aBackground);
|
||||||
return hasForeground || hasBackground;
|
return hasForeground || hasBackground;
|
||||||
}
|
}
|
||||||
|
case SelectionType::eTargetText: {
|
||||||
|
aTextPaintStyle.GetTargetTextColors(aForeground, aBackground);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
case SelectionType::eURLSecondary:
|
case SelectionType::eURLSecondary:
|
||||||
aTextPaintStyle.GetURLSecondaryColor(aForeground);
|
aTextPaintStyle.GetURLSecondaryColor(aForeground);
|
||||||
*aBackground = NS_RGBA(0, 0, 0, 0);
|
*aBackground = NS_RGBA(0, 0, 0, 0);
|
||||||
|
|||||||
@@ -213,6 +213,24 @@ void nsTextPaintStyle::GetHighlightColors(nscolor* aForeColor,
|
|||||||
*aBackColor = NS_TRANSPARENT;
|
*aBackColor = NS_TRANSPARENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nsTextPaintStyle::GetTargetTextColors(nscolor* aForeColor,
|
||||||
|
nscolor* aBackColor) {
|
||||||
|
NS_ASSERTION(aForeColor, "aForeColor is null");
|
||||||
|
NS_ASSERTION(aBackColor, "aBackColor is null");
|
||||||
|
const RefPtr<const ComputedStyle> targetTextStyle =
|
||||||
|
mFrame->ComputeTargetTextStyle();
|
||||||
|
if (targetTextStyle) {
|
||||||
|
*aForeColor = targetTextStyle->GetVisitedDependentColor(
|
||||||
|
&nsStyleText::mWebkitTextFillColor);
|
||||||
|
*aBackColor = targetTextStyle->GetVisitedDependentColor(
|
||||||
|
&nsStyleBackground::mBackgroundColor);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// XXX(:jjaschke): Before shipping this feature, a sensible set of colors must
|
||||||
|
// be set (Bug 1867940).
|
||||||
|
// in the meantime, use the colors of find selection.
|
||||||
|
GetHighlightColors(aForeColor, aBackColor);
|
||||||
|
}
|
||||||
bool nsTextPaintStyle::GetCustomHighlightTextColor(nsAtom* aHighlightName,
|
bool nsTextPaintStyle::GetCustomHighlightTextColor(nsAtom* aHighlightName,
|
||||||
nscolor* aForeColor) {
|
nscolor* aForeColor) {
|
||||||
NS_ASSERTION(aForeColor, "aForeColor is null");
|
NS_ASSERTION(aForeColor, "aForeColor is null");
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ class MOZ_STACK_CLASS nsTextPaintStyle {
|
|||||||
*/
|
*/
|
||||||
bool GetSelectionColors(nscolor* aForeColor, nscolor* aBackColor);
|
bool GetSelectionColors(nscolor* aForeColor, nscolor* aBackColor);
|
||||||
void GetHighlightColors(nscolor* aForeColor, nscolor* aBackColor);
|
void GetHighlightColors(nscolor* aForeColor, nscolor* aBackColor);
|
||||||
|
void GetTargetTextColors(nscolor* aForeColor, nscolor* aBackColor);
|
||||||
// Computes colors for custom highlights.
|
// Computes colors for custom highlights.
|
||||||
// Returns false if there are no rules associated with `aHighlightName`.
|
// Returns false if there are no rules associated with `aHighlightName`.
|
||||||
bool GetCustomHighlightTextColor(nsAtom* aHighlightName, nscolor* aForeColor);
|
bool GetCustomHighlightTextColor(nsAtom* aHighlightName, nscolor* aForeColor);
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
"::highlight",
|
"::highlight",
|
||||||
"::placeholder",
|
"::placeholder",
|
||||||
"::selection",
|
"::selection",
|
||||||
|
"::target-text",
|
||||||
"::-moz-color-swatch",
|
"::-moz-color-swatch",
|
||||||
"::-moz-focus-inner",
|
"::-moz-focus-inner",
|
||||||
"::-moz-meter-bar",
|
"::-moz-meter-bar",
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ CSS_PSEUDO_ELEMENT(highlight, ":highlight", 0)
|
|||||||
CSS_PSEUDO_ELEMENT(selection, ":selection",
|
CSS_PSEUDO_ELEMENT(selection, ":selection",
|
||||||
CSS_PSEUDO_ELEMENT_CONTAINS_ELEMENTS)
|
CSS_PSEUDO_ELEMENT_CONTAINS_ELEMENTS)
|
||||||
|
|
||||||
|
CSS_PSEUDO_ELEMENT(targetText, ":target-text", 0)
|
||||||
// XXXbz should we really allow random content to style these? Maybe
|
// XXXbz should we really allow random content to style these? Maybe
|
||||||
// use our flags to prevent that?
|
// use our flags to prevent that?
|
||||||
CSS_PSEUDO_ELEMENT(mozFocusInner, ":-moz-focus-inner", 0)
|
CSS_PSEUDO_ELEMENT(mozFocusInner, ":-moz-focus-inner", 0)
|
||||||
|
|||||||
@@ -130,6 +130,8 @@ class nsCSSPseudoElements {
|
|||||||
switch (aType) {
|
switch (aType) {
|
||||||
case Type::highlight:
|
case Type::highlight:
|
||||||
return mozilla::StaticPrefs::dom_customHighlightAPI_enabled();
|
return mozilla::StaticPrefs::dom_customHighlightAPI_enabled();
|
||||||
|
case Type::targetText:
|
||||||
|
return mozilla::StaticPrefs::dom_text_fragments_enabled();
|
||||||
case Type::sliderTrack:
|
case Type::sliderTrack:
|
||||||
case Type::sliderThumb:
|
case Type::sliderThumb:
|
||||||
case Type::sliderFill:
|
case Type::sliderFill:
|
||||||
|
|||||||
@@ -159,6 +159,11 @@ impl PseudoElement {
|
|||||||
matches!(*self, Self::Highlight(_))
|
matches!(*self, Self::Highlight(_))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Whether this pseudo-element is the ::target-text pseudo.
|
||||||
|
#[inline]
|
||||||
|
pub fn is_target_text(&self) -> bool {
|
||||||
|
*self == PseudoElement::TargetText
|
||||||
|
}
|
||||||
/// Whether this pseudo-element supports user action selectors.
|
/// Whether this pseudo-element supports user action selectors.
|
||||||
pub fn supports_user_action_state(&self) -> bool {
|
pub fn supports_user_action_state(&self) -> bool {
|
||||||
(self.flags() & structs::CSS_PSEUDO_ELEMENT_SUPPORTS_USER_ACTION_STATE) != 0
|
(self.flags() & structs::CSS_PSEUDO_ELEMENT_SUPPORTS_USER_ACTION_STATE) != 0
|
||||||
@@ -168,6 +173,7 @@ impl PseudoElement {
|
|||||||
pub fn enabled_in_content(&self) -> bool {
|
pub fn enabled_in_content(&self) -> bool {
|
||||||
match *self {
|
match *self {
|
||||||
Self::Highlight(..) => pref!("dom.customHighlightAPI.enabled"),
|
Self::Highlight(..) => pref!("dom.customHighlightAPI.enabled"),
|
||||||
|
Self::TargetText => pref!("dom.text_fragments.enabled"),
|
||||||
Self::SliderFill | Self::SliderTrack | Self::SliderThumb => {
|
Self::SliderFill | Self::SliderTrack | Self::SliderThumb => {
|
||||||
pref!("layout.css.modern-range-pseudos.enabled")
|
pref!("layout.css.modern-range-pseudos.enabled")
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -2486,6 +2486,7 @@ STATIC_ATOMS = [
|
|||||||
PseudoElementAtom("PseudoElement_firstLine", ":first-line"),
|
PseudoElementAtom("PseudoElement_firstLine", ":first-line"),
|
||||||
PseudoElementAtom("PseudoElement_highlight", ":highlight"),
|
PseudoElementAtom("PseudoElement_highlight", ":highlight"),
|
||||||
PseudoElementAtom("PseudoElement_selection", ":selection"),
|
PseudoElementAtom("PseudoElement_selection", ":selection"),
|
||||||
|
PseudoElementAtom("PseudoElement_targetText", ":target-text"),
|
||||||
PseudoElementAtom("PseudoElement_mozFocusInner", ":-moz-focus-inner"),
|
PseudoElementAtom("PseudoElement_mozFocusInner", ":-moz-focus-inner"),
|
||||||
PseudoElementAtom("PseudoElement_mozNumberSpinBox", ":-moz-number-spin-box"),
|
PseudoElementAtom("PseudoElement_mozNumberSpinBox", ":-moz-number-spin-box"),
|
||||||
PseudoElementAtom("PseudoElement_mozNumberSpinUp", ":-moz-number-spin-up"),
|
PseudoElementAtom("PseudoElement_mozNumberSpinUp", ":-moz-number-spin-up"),
|
||||||
|
|||||||
Reference in New Issue
Block a user