This change implements the rounded selection highlight used in the new Nova
design for the urlbar. [1]
This patch makes the following properties available in the ::selection
pseudo-element in chrome-privileged contexts.
- border-radius
- border-top-left-radius
- border-top-right-radius
- border-bottom-left-radius
- border-bottom-right-radius
For example to set up the radius:
```
.urlbar-input::selection {
border-radius: 4px;
}
```
[1] https://www.figma.com/design/WMHwWMwIu6SDzJyvVUn33X/S-S-UX-Specifications–Sprint-2-?node-id=13056-9952&t=pswCcokl3etqlyZU-1
Differential Revision: https://phabricator.services.mozilla.com/D289127
185 lines
6.6 KiB
C++
185 lines
6.6 KiB
C++
/* 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/. */
|
|
|
|
#ifndef nsTextPaintStyle_h_
|
|
#define nsTextPaintStyle_h_
|
|
|
|
#include "mozilla/Attributes.h"
|
|
#include "mozilla/ComputedStyle.h"
|
|
#include "mozilla/EnumeratedArray.h"
|
|
#include "mozilla/Span.h"
|
|
#include "nsAtomHashKeys.h"
|
|
#include "nsISelectionController.h"
|
|
#include "nsTHashMap.h"
|
|
|
|
class nsTextFrame;
|
|
class nsPresContext;
|
|
|
|
namespace mozilla {
|
|
enum class StyleTextDecorationStyle : uint8_t;
|
|
}
|
|
|
|
/**
|
|
* This helper object computes colors used for painting, and also IME
|
|
* underline information. The data is computed lazily and cached as necessary.
|
|
* These live for just the duration of one paint operation.
|
|
*/
|
|
class MOZ_STACK_CLASS nsTextPaintStyle {
|
|
using ComputedStyle = mozilla::ComputedStyle;
|
|
using SelectionType = mozilla::SelectionType;
|
|
using StyleTextDecorationStyle = mozilla::StyleTextDecorationStyle;
|
|
using StyleSimpleShadow = mozilla::StyleSimpleShadow;
|
|
|
|
public:
|
|
explicit nsTextPaintStyle(nsTextFrame* aFrame);
|
|
|
|
void SetResolveColors(bool aResolveColors) {
|
|
mResolveColors = aResolveColors;
|
|
}
|
|
|
|
nscolor GetTextColor();
|
|
|
|
// SVG text has its own painting process, so we should never get its stroke
|
|
// property from here.
|
|
nscolor GetWebkitTextStrokeColor();
|
|
float GetWebkitTextStrokeWidth();
|
|
|
|
// Index used to look up styles for different types of selection.
|
|
enum class SelectionStyleIndex : uint8_t {
|
|
RawInput = 0,
|
|
SelRawText,
|
|
ConvText,
|
|
SelConvText,
|
|
SpellChecker,
|
|
// Not an actual enum value; used to size the array of styles.
|
|
Count,
|
|
};
|
|
|
|
/**
|
|
* Compute the colors for normally-selected text. Returns false if
|
|
* the normal selection is not being displayed.
|
|
*/
|
|
bool GetSelectionColors(nscolor* aForeColor, nscolor* aBackColor);
|
|
void GetHighlightColors(nscolor* aForeColor, nscolor* aBackColor);
|
|
// Returns true if the author has specified a text color.
|
|
// Always sets a value into `aForeColor`.
|
|
bool GetTargetTextColor(nscolor* aForeColor);
|
|
// Returns true if the target text background is being displayed.
|
|
// Always sets a value into `aBackColor`.
|
|
bool GetTargetTextBackgroundColor(nscolor* aBackColor);
|
|
mozilla::Span<const StyleSimpleShadow> GetTargetTextShadow();
|
|
// Computes colors for custom highlights.
|
|
// Returns false if there are no rules associated with `aHighlightName`.
|
|
bool GetCustomHighlightTextColor(nsAtom* aHighlightName, nscolor* aForeColor);
|
|
bool GetCustomHighlightBackgroundColor(nsAtom* aHighlightName,
|
|
nscolor* aBackColor);
|
|
mozilla::Span<const StyleSimpleShadow> GetCustomHighlightTextShadow(
|
|
nsAtom* aHighlightName);
|
|
RefPtr<ComputedStyle> GetComputedStyleForSelectionPseudo(
|
|
SelectionType aSelectionType, nsAtom* aHighlightName);
|
|
|
|
void GetURLSecondaryColor(nscolor* aForeColor);
|
|
void GetIMESelectionColors(SelectionStyleIndex aIndex, nscolor* aForeColor,
|
|
nscolor* aBackColor);
|
|
// if this returns false, we don't need to draw underline.
|
|
bool GetSelectionUnderlineForPaint(SelectionStyleIndex aIndex,
|
|
nscolor* aLineColor, float* aRelativeSize,
|
|
StyleTextDecorationStyle* aStyle);
|
|
|
|
// if this returns false, we don't need to draw underline.
|
|
static bool GetSelectionUnderline(nsIFrame*, SelectionStyleIndex aIndex,
|
|
nscolor* aLineColor, float* aRelativeSize,
|
|
StyleTextDecorationStyle* aStyle);
|
|
|
|
mozilla::Span<const StyleSimpleShadow> GetSelectionShadow();
|
|
|
|
nsPresContext* PresContext() const { return mPresContext; }
|
|
|
|
static SelectionStyleIndex GetUnderlineStyleIndexForSelectionType(
|
|
SelectionType aSelectionType) {
|
|
switch (aSelectionType) {
|
|
case SelectionType::eIMERawClause:
|
|
return SelectionStyleIndex::RawInput;
|
|
case SelectionType::eIMESelectedRawClause:
|
|
return SelectionStyleIndex::SelRawText;
|
|
case SelectionType::eIMEConvertedClause:
|
|
return SelectionStyleIndex::ConvText;
|
|
case SelectionType::eIMESelectedClause:
|
|
return SelectionStyleIndex::SelConvText;
|
|
case SelectionType::eSpellCheck:
|
|
return SelectionStyleIndex::SpellChecker;
|
|
default:
|
|
NS_WARNING("non-IME selection type");
|
|
return SelectionStyleIndex::RawInput;
|
|
}
|
|
}
|
|
|
|
nscolor GetSystemFieldForegroundColor();
|
|
nscolor GetSystemFieldBackgroundColor();
|
|
|
|
const ComputedStyle* GetSelectionPseudoStyle() const {
|
|
return mSelectionPseudoStyle;
|
|
}
|
|
|
|
protected:
|
|
nsTextFrame* mFrame;
|
|
nsPresContext* mPresContext;
|
|
bool mInitCommonColors;
|
|
bool mInitSelectionColorsAndShadow;
|
|
bool mResolveColors;
|
|
bool mInitTargetTextPseudoStyle;
|
|
mozilla::Maybe<bool> mTargetTextUseLightScheme;
|
|
|
|
// Selection data
|
|
|
|
nscolor mSelectionTextColor;
|
|
nscolor mSelectionBGColor;
|
|
RefPtr<ComputedStyle> mSelectionPseudoStyle;
|
|
RefPtr<ComputedStyle> mTargetTextPseudoStyle;
|
|
nsTHashMap<RefPtr<nsAtom>, RefPtr<ComputedStyle>>
|
|
mCustomHighlightPseudoStyles;
|
|
|
|
// Common data
|
|
|
|
int32_t mSufficientContrast;
|
|
nscolor mFrameBackgroundColor;
|
|
nscolor mSystemFieldForegroundColor;
|
|
nscolor mSystemFieldBackgroundColor;
|
|
|
|
// selection colors and underline info, the colors are resolved colors if
|
|
// mResolveColors is true (which is the default), i.e., the foreground color
|
|
// and background color are swapped if it's needed. And also line color will
|
|
// be resolved from them.
|
|
struct nsSelectionStyle {
|
|
nscolor mTextColor;
|
|
nscolor mBGColor;
|
|
nscolor mUnderlineColor;
|
|
StyleTextDecorationStyle mUnderlineStyle;
|
|
float mUnderlineRelativeSize;
|
|
};
|
|
mozilla::EnumeratedArray<SelectionStyleIndex,
|
|
mozilla::Maybe<nsSelectionStyle>,
|
|
size_t(SelectionStyleIndex::Count)>
|
|
mSelectionStyle;
|
|
|
|
// Color initializations
|
|
void InitCommonColors();
|
|
bool InitSelectionColorsAndShadow();
|
|
void InitTargetTextPseudoStyle();
|
|
bool TargetTextUseLightScheme();
|
|
|
|
nsSelectionStyle* SelectionStyle(SelectionStyleIndex aIndex);
|
|
nsSelectionStyle InitSelectionStyle(SelectionStyleIndex aIndex);
|
|
|
|
// Ensures sufficient contrast between the frame background color and the
|
|
// selection background color, and swaps the selection text and background
|
|
// colors accordingly.
|
|
bool EnsureSufficientContrast(nscolor* aForeColor, nscolor* aBackColor);
|
|
|
|
nscolor GetResolvedForeColor(nscolor aColor, nscolor aDefaultForeColor,
|
|
nscolor aBackColor);
|
|
};
|
|
|
|
#endif // nsTextPaintStyle_h_
|