mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 13:21:05 +00:00
Bug 1711479 - Implement CSS support for the optional adjustment-basis metric keywords for the font-size-adjust property (enabled on Nightly only for now). r=emilio
Differential Revision: https://phabricator.services.mozilla.com/D115596
This commit is contained in:
parent
d89225f30d
commit
57c18282b4
@ -40,9 +40,9 @@ struct nsFont final {
|
|||||||
|
|
||||||
// The aspect-value (ie., the ratio actualsize:actualxheight) that any
|
// The aspect-value (ie., the ratio actualsize:actualxheight) that any
|
||||||
// actual physical font created from this font structure must have when
|
// actual physical font created from this font structure must have when
|
||||||
// rendering or measuring a string. A value of -1.0 means no adjustment
|
// rendering or measuring a string. The value must be nonnegative.
|
||||||
// needs to be done; otherwise the value must be nonnegative.
|
mozilla::StyleFontSizeAdjust sizeAdjust =
|
||||||
float sizeAdjust = -1.0f;
|
mozilla::StyleFontSizeAdjust::None();
|
||||||
|
|
||||||
// The estimated background color behind the text. Enables a special
|
// The estimated background color behind the text. Enables a special
|
||||||
// rendering mode when NS_GET_A(.) > 0. Only used for text in the chrome.
|
// rendering mode when NS_GET_A(.) > 0. Only used for text in the chrome.
|
||||||
|
@ -119,7 +119,8 @@ nsFontMetrics::nsFontMetrics(const nsFont& aFont, const Params& aParams,
|
|||||||
mVertical(false),
|
mVertical(false),
|
||||||
mTextOrientation(mozilla::StyleTextOrientation::Mixed) {
|
mTextOrientation(mozilla::StyleTextOrientation::Mixed) {
|
||||||
gfxFontStyle style(aFont.style, aFont.weight, aFont.stretch,
|
gfxFontStyle style(aFont.style, aFont.weight, aFont.stretch,
|
||||||
gfxFloat(aFont.size.ToAppUnits()) / mP2A, aFont.sizeAdjust,
|
gfxFloat(aFont.size.ToAppUnits()) / mP2A,
|
||||||
|
aFont.sizeAdjust.IsEx() ? aFont.sizeAdjust.AsEx() : -1.0f,
|
||||||
aFont.systemFont, mDeviceContext->IsPrinterContext(),
|
aFont.systemFont, mDeviceContext->IsPrinterContext(),
|
||||||
aFont.synthesis & NS_FONT_SYNTHESIS_WEIGHT,
|
aFont.synthesis & NS_FONT_SYNTHESIS_WEIGHT,
|
||||||
aFont.synthesis & NS_FONT_SYNTHESIS_STYLE,
|
aFont.synthesis & NS_FONT_SYNTHESIS_STYLE,
|
||||||
|
@ -195,7 +195,7 @@ void LangGroupFontPrefs::Initialize(nsStaticAtom* aLangGroupAtom) {
|
|||||||
nsAutoCString cvalue;
|
nsAutoCString cvalue;
|
||||||
Preferences::GetCString(pref.get(), cvalue);
|
Preferences::GetCString(pref.get(), cvalue);
|
||||||
if (!cvalue.IsEmpty()) {
|
if (!cvalue.IsEmpty()) {
|
||||||
font->sizeAdjust = (float)atof(cvalue.get());
|
font->sizeAdjust = StyleFontSizeAdjust::Ex((float)atof(cvalue.get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_rbs
|
#ifdef DEBUG_rbs
|
||||||
|
@ -9581,7 +9581,9 @@ void nsLayoutUtils::ComputeSystemFont(nsFont* aSystemFont,
|
|||||||
aSystemFont->size = Length::FromPixels(fontStyle.size);
|
aSystemFont->size = Length::FromPixels(fontStyle.size);
|
||||||
|
|
||||||
// aSystemFont->langGroup = fontStyle.langGroup;
|
// aSystemFont->langGroup = fontStyle.langGroup;
|
||||||
aSystemFont->sizeAdjust = fontStyle.sizeAdjust;
|
aSystemFont->sizeAdjust = fontStyle.sizeAdjust < 0.0
|
||||||
|
? StyleFontSizeAdjust::None()
|
||||||
|
: StyleFontSizeAdjust::Ex(fontStyle.sizeAdjust);
|
||||||
|
|
||||||
if (aFontID == LookAndFeel::FontID::MozField ||
|
if (aFontID == LookAndFeel::FontID::MozField ||
|
||||||
aFontID == LookAndFeel::FontID::MozButton ||
|
aFontID == LookAndFeel::FontID::MozButton ||
|
||||||
|
@ -504,6 +504,7 @@ cbindgen-types = [
|
|||||||
{ gecko = "StyleOwnedOrNull", servo = "crate::gecko_bindings::sugar::ownership::OwnedOrNull" },
|
{ gecko = "StyleOwnedOrNull", servo = "crate::gecko_bindings::sugar::ownership::OwnedOrNull" },
|
||||||
{ gecko = "StyleStrong", servo = "crate::gecko_bindings::sugar::ownership::Strong" },
|
{ gecko = "StyleStrong", servo = "crate::gecko_bindings::sugar::ownership::Strong" },
|
||||||
{ gecko = "StyleGenericFontFamily", servo = "crate::values::computed::font::GenericFontFamily" },
|
{ gecko = "StyleGenericFontFamily", servo = "crate::values::computed::font::GenericFontFamily" },
|
||||||
|
{ gecko = "StyleGenericFontSizeAdjust", servo = "crate::values::generics::font::GenericFontSizeAdjust" },
|
||||||
{ gecko = "StyleFontFamilyNameSyntax", servo = "crate::values::computed::font::FontFamilyNameSyntax" },
|
{ gecko = "StyleFontFamilyNameSyntax", servo = "crate::values::computed::font::FontFamilyNameSyntax" },
|
||||||
{ gecko = "StyleGenericColor", servo = "crate::values::generics::color::Color" },
|
{ gecko = "StyleGenericColor", servo = "crate::values::generics::color::Color" },
|
||||||
{ gecko = "StyleSystemColor", servo = "crate::values::specified::color::SystemColor" },
|
{ gecko = "StyleSystemColor", servo = "crate::values::specified::color::SystemColor" },
|
||||||
|
@ -6842,6 +6842,13 @@
|
|||||||
mirror: always
|
mirror: always
|
||||||
rust: true
|
rust: true
|
||||||
|
|
||||||
|
# Is the optional adjustment-basis value for font-size-adjust enabled?
|
||||||
|
- name: layout.css.font-size-adjust.basis.enabled
|
||||||
|
type: RelaxedAtomicBool
|
||||||
|
value: @IS_NIGHTLY_BUILD@
|
||||||
|
mirror: always
|
||||||
|
rust: true
|
||||||
|
|
||||||
# Visibility level of font families available to CSS font-matching:
|
# Visibility level of font families available to CSS font-matching:
|
||||||
# 1 - only base system fonts
|
# 1 - only base system fonts
|
||||||
# 2 - also fonts from optional language packs
|
# 2 - also fonts from optional language packs
|
||||||
|
@ -1008,26 +1008,7 @@ fn static_assert() {
|
|||||||
|
|
||||||
${impl_simple("font_variant_alternates", "mFont.variantAlternates")}
|
${impl_simple("font_variant_alternates", "mFont.variantAlternates")}
|
||||||
|
|
||||||
pub fn set_font_size_adjust(&mut self, v: longhands::font_size_adjust::computed_value::T) {
|
${impl_simple("font_size_adjust", "mFont.sizeAdjust")}
|
||||||
use crate::properties::longhands::font_size_adjust::computed_value::T;
|
|
||||||
match v {
|
|
||||||
T::None => self.gecko.mFont.sizeAdjust = -1.0 as f32,
|
|
||||||
T::Number(n) => self.gecko.mFont.sizeAdjust = n,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn copy_font_size_adjust_from(&mut self, other: &Self) {
|
|
||||||
self.gecko.mFont.sizeAdjust = other.gecko.mFont.sizeAdjust;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn reset_font_size_adjust(&mut self, other: &Self) {
|
|
||||||
self.copy_font_size_adjust_from(other)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn clone_font_size_adjust(&self) -> longhands::font_size_adjust::computed_value::T {
|
|
||||||
use crate::properties::longhands::font_size_adjust::computed_value::T;
|
|
||||||
T::from_gecko_adjust(self.gecko.mFont.sizeAdjust)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub fn set__x_lang(&mut self, v: longhands::_x_lang::computed_value::T) {
|
pub fn set__x_lang(&mut self, v: longhands::_x_lang::computed_value::T) {
|
||||||
|
@ -383,8 +383,7 @@ pub mod system_font {
|
|||||||
font_weight,
|
font_weight,
|
||||||
font_stretch,
|
font_stretch,
|
||||||
font_style,
|
font_style,
|
||||||
font_size_adjust: longhands::font_size_adjust::computed_value
|
font_size_adjust: system.sizeAdjust,
|
||||||
::T::from_gecko_adjust(system.sizeAdjust),
|
|
||||||
% for kwprop in kw_font_props:
|
% for kwprop in kw_font_props:
|
||||||
${kwprop}: longhands::${kwprop}::computed_value::T::from_gecko_keyword(
|
${kwprop}: longhands::${kwprop}::computed_value::T::from_gecko_keyword(
|
||||||
system.${to_camel_case_lower(kwprop.replace('font_', ''))}
|
system.${to_camel_case_lower(kwprop.replace('font_', ''))}
|
||||||
|
@ -8,9 +8,9 @@
|
|||||||
use crate::gecko_bindings::sugar::refptr::RefPtr;
|
use crate::gecko_bindings::sugar::refptr::RefPtr;
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
use crate::gecko_bindings::{bindings, structs};
|
use crate::gecko_bindings::{bindings, structs};
|
||||||
use crate::values::animated::{ToAnimatedValue, ToAnimatedZero};
|
use crate::values::animated::ToAnimatedValue;
|
||||||
use crate::values::computed::{
|
use crate::values::computed::{
|
||||||
Angle, Context, Integer, Length, NonNegativeLength, NonNegativePercentage,
|
Angle, Context, Integer, Length, NonNegativeLength, NonNegativeNumber, NonNegativePercentage,
|
||||||
};
|
};
|
||||||
use crate::values::computed::{Number, Percentage, ToComputedValue};
|
use crate::values::computed::{Number, Percentage, ToComputedValue};
|
||||||
use crate::values::generics::font::{FeatureTagValue, FontSettings, VariationValue};
|
use crate::values::generics::font::{FeatureTagValue, FontSettings, VariationValue};
|
||||||
@ -623,24 +623,7 @@ impl<'a> Iterator for FontFamilyNameIter<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Preserve the readability of text when font fallback occurs
|
/// Preserve the readability of text when font fallback occurs
|
||||||
#[derive(
|
pub type FontSizeAdjust = generics::GenericFontSizeAdjust<NonNegativeNumber>;
|
||||||
Animate,
|
|
||||||
Clone,
|
|
||||||
ComputeSquaredDistance,
|
|
||||||
Copy,
|
|
||||||
Debug,
|
|
||||||
MallocSizeOf,
|
|
||||||
PartialEq,
|
|
||||||
ToCss,
|
|
||||||
ToResolvedValue,
|
|
||||||
)]
|
|
||||||
pub enum FontSizeAdjust {
|
|
||||||
#[animation(error)]
|
|
||||||
/// None variant
|
|
||||||
None,
|
|
||||||
/// Number variant
|
|
||||||
Number(CSSFloat),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FontSizeAdjust {
|
impl FontSizeAdjust {
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -648,40 +631,6 @@ impl FontSizeAdjust {
|
|||||||
pub fn none() -> Self {
|
pub fn none() -> Self {
|
||||||
FontSizeAdjust::None
|
FontSizeAdjust::None
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get font-size-adjust with float number
|
|
||||||
pub fn from_gecko_adjust(gecko: f32) -> Self {
|
|
||||||
if gecko == -1.0 {
|
|
||||||
FontSizeAdjust::None
|
|
||||||
} else {
|
|
||||||
FontSizeAdjust::Number(gecko)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToAnimatedZero for FontSizeAdjust {
|
|
||||||
#[inline]
|
|
||||||
// FIXME(emilio): why?
|
|
||||||
fn to_animated_zero(&self) -> Result<Self, ()> {
|
|
||||||
Err(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToAnimatedValue for FontSizeAdjust {
|
|
||||||
type AnimatedValue = Self;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn to_animated_value(self) -> Self {
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn from_animated_value(animated: Self::AnimatedValue) -> Self {
|
|
||||||
match animated {
|
|
||||||
FontSizeAdjust::Number(number) => FontSizeAdjust::Number(number.max(0.)),
|
|
||||||
_ => animated,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Use VariantAlternatesList as computed type of FontVariantAlternates
|
/// Use VariantAlternatesList as computed type of FontVariantAlternates
|
||||||
|
@ -202,3 +202,56 @@ pub enum FontStyle<Angle> {
|
|||||||
#[value_info(starts_with_keyword)]
|
#[value_info(starts_with_keyword)]
|
||||||
Oblique(Angle),
|
Oblique(Angle),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A generic value for the `font-size-adjust` property.
|
||||||
|
///
|
||||||
|
/// https://www.w3.org/TR/css-fonts-4/#font-size-adjust-prop
|
||||||
|
/// https://github.com/w3c/csswg-drafts/issues/6160
|
||||||
|
#[allow(missing_docs)]
|
||||||
|
#[repr(u8)]
|
||||||
|
#[derive(
|
||||||
|
Animate,
|
||||||
|
Clone,
|
||||||
|
ComputeSquaredDistance,
|
||||||
|
Copy,
|
||||||
|
Debug,
|
||||||
|
Hash,
|
||||||
|
MallocSizeOf,
|
||||||
|
PartialEq,
|
||||||
|
SpecifiedValueInfo,
|
||||||
|
ToAnimatedValue,
|
||||||
|
ToAnimatedZero,
|
||||||
|
ToComputedValue,
|
||||||
|
ToResolvedValue,
|
||||||
|
ToShmem,
|
||||||
|
)]
|
||||||
|
pub enum GenericFontSizeAdjust<Number> {
|
||||||
|
#[animation(error)]
|
||||||
|
None,
|
||||||
|
// 'ex' is the implied basis, so the keyword can be omitted
|
||||||
|
Ex(Number),
|
||||||
|
#[value_info(starts_with_keyword)]
|
||||||
|
Cap(Number),
|
||||||
|
#[value_info(starts_with_keyword)]
|
||||||
|
Ch(Number),
|
||||||
|
#[value_info(starts_with_keyword)]
|
||||||
|
Ic(Number),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Number: ToCss> ToCss for GenericFontSizeAdjust<Number> {
|
||||||
|
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
||||||
|
where
|
||||||
|
W: Write,
|
||||||
|
{
|
||||||
|
let (prefix, value) = match self {
|
||||||
|
Self::None => return dest.write_str("none"),
|
||||||
|
Self::Ex(v) => ("", v),
|
||||||
|
Self::Cap(v) => ("cap ", v),
|
||||||
|
Self::Ch(v) => ("ch ", v),
|
||||||
|
Self::Ic(v) => ("ic ", v),
|
||||||
|
};
|
||||||
|
|
||||||
|
dest.write_str(prefix)?;
|
||||||
|
value.to_css(dest)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -11,8 +11,9 @@ use crate::values::computed::font::{FamilyName, FontFamilyList, FontStyleAngle,
|
|||||||
use crate::values::computed::{font as computed, Length, NonNegativeLength};
|
use crate::values::computed::{font as computed, Length, NonNegativeLength};
|
||||||
use crate::values::computed::{Angle as ComputedAngle, Percentage as ComputedPercentage};
|
use crate::values::computed::{Angle as ComputedAngle, Percentage as ComputedPercentage};
|
||||||
use crate::values::computed::{CSSPixelLength, Context, ToComputedValue};
|
use crate::values::computed::{CSSPixelLength, Context, ToComputedValue};
|
||||||
|
use crate::values::computed::FontSizeAdjust as ComputedFontSizeAdjust;
|
||||||
use crate::values::generics::font::VariationValue;
|
use crate::values::generics::font::VariationValue;
|
||||||
use crate::values::generics::font::{self as generics, FeatureTagValue, FontSettings, FontTag};
|
use crate::values::generics::font::{self as generics, FeatureTagValue, FontSettings, FontTag, GenericFontSizeAdjust};
|
||||||
use crate::values::generics::NonNegative;
|
use crate::values::generics::NonNegative;
|
||||||
use crate::values::specified::length::{FontBaseSize, AU_PER_PT, AU_PER_PX};
|
use crate::values::specified::length::{FontBaseSize, AU_PER_PT, AU_PER_PX};
|
||||||
use crate::values::specified::{AllowQuirks, Angle, Integer, LengthPercentage};
|
use crate::values::specified::{AllowQuirks, Angle, Integer, LengthPercentage};
|
||||||
@ -738,16 +739,13 @@ impl Parse for FamilyName {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(
|
|
||||||
Clone, Copy, Debug, MallocSizeOf, Parse, PartialEq, SpecifiedValueInfo, ToCss, ToShmem,
|
|
||||||
)]
|
|
||||||
/// Preserve the readability of text when font fallback occurs
|
/// Preserve the readability of text when font fallback occurs
|
||||||
|
#[derive(
|
||||||
|
Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss, ToShmem,
|
||||||
|
)]
|
||||||
|
#[allow(missing_docs)]
|
||||||
pub enum FontSizeAdjust {
|
pub enum FontSizeAdjust {
|
||||||
/// None variant
|
Value(GenericFontSizeAdjust<NonNegativeNumber>),
|
||||||
None,
|
|
||||||
/// Number variant
|
|
||||||
Number(NonNegativeNumber),
|
|
||||||
/// system font
|
|
||||||
#[css(skip)]
|
#[css(skip)]
|
||||||
System(SystemFont),
|
System(SystemFont),
|
||||||
}
|
}
|
||||||
@ -756,34 +754,53 @@ impl FontSizeAdjust {
|
|||||||
#[inline]
|
#[inline]
|
||||||
/// Default value of font-size-adjust
|
/// Default value of font-size-adjust
|
||||||
pub fn none() -> Self {
|
pub fn none() -> Self {
|
||||||
FontSizeAdjust::None
|
FontSizeAdjust::Value(GenericFontSizeAdjust::None)
|
||||||
}
|
}
|
||||||
|
|
||||||
system_font_methods!(FontSizeAdjust, font_size_adjust);
|
system_font_methods!(FontSizeAdjust, font_size_adjust);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Parse for FontSizeAdjust {
|
||||||
|
fn parse<'i, 't>(
|
||||||
|
context: &ParserContext,
|
||||||
|
input: &mut Parser<'i, 't>,
|
||||||
|
) -> Result<Self, ParseError<'i>> {
|
||||||
|
let location = input.current_source_location();
|
||||||
|
if let Ok(ident) = input.try_parse(|i| i.expect_ident_cloned()) {
|
||||||
|
let basis_enabled = static_prefs::pref!("layout.css.font-size-adjust.basis.enabled");
|
||||||
|
let basis = match_ignore_ascii_case! { &ident,
|
||||||
|
"none" => return Ok(FontSizeAdjust::none()),
|
||||||
|
// Check for size adjustment basis keywords if enabled.
|
||||||
|
"ex" if basis_enabled => GenericFontSizeAdjust::Ex,
|
||||||
|
"cap" if basis_enabled => GenericFontSizeAdjust::Cap,
|
||||||
|
"ch" if basis_enabled => GenericFontSizeAdjust::Ch,
|
||||||
|
"ic" if basis_enabled => GenericFontSizeAdjust::Ic,
|
||||||
|
// Unknown (or disabled) keyword.
|
||||||
|
_ => return Err(location.new_custom_error(
|
||||||
|
::selectors::parser::SelectorParseErrorKind::UnexpectedIdent(ident)
|
||||||
|
)),
|
||||||
|
};
|
||||||
|
let value = NonNegativeNumber::parse(context, input)?;
|
||||||
|
return Ok(FontSizeAdjust::Value(basis(value)));
|
||||||
|
}
|
||||||
|
// Without a basis keyword, the number refers to the 'ex' metric.
|
||||||
|
let value = NonNegativeNumber::parse(context, input)?;
|
||||||
|
Ok(FontSizeAdjust::Value(GenericFontSizeAdjust::Ex(value)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ToComputedValue for FontSizeAdjust {
|
impl ToComputedValue for FontSizeAdjust {
|
||||||
type ComputedValue = computed::FontSizeAdjust;
|
type ComputedValue = ComputedFontSizeAdjust;
|
||||||
|
|
||||||
fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
|
fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
|
||||||
match *self {
|
match *self {
|
||||||
FontSizeAdjust::None => computed::FontSizeAdjust::None,
|
FontSizeAdjust::Value(v) => v.to_computed_value(context),
|
||||||
FontSizeAdjust::Number(ref n) => {
|
|
||||||
// The computed version handles clamping of animated values
|
|
||||||
// itself.
|
|
||||||
computed::FontSizeAdjust::Number(n.to_computed_value(context).0)
|
|
||||||
},
|
|
||||||
FontSizeAdjust::System(_) => self.compute_system(context),
|
FontSizeAdjust::System(_) => self.compute_system(context),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_computed_value(computed: &computed::FontSizeAdjust) -> Self {
|
fn from_computed_value(computed: &ComputedFontSizeAdjust) -> Self {
|
||||||
match *computed {
|
Self::Value(ToComputedValue::from_computed_value(computed))
|
||||||
computed::FontSizeAdjust::None => FontSizeAdjust::None,
|
|
||||||
computed::FontSizeAdjust::Number(v) => {
|
|
||||||
FontSizeAdjust::Number(NonNegativeNumber::from_computed_value(&v.into()))
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,6 +80,7 @@ include = [
|
|||||||
"BorderStyle",
|
"BorderStyle",
|
||||||
"OutlineStyle",
|
"OutlineStyle",
|
||||||
"CaptionSide",
|
"CaptionSide",
|
||||||
|
"FontSizeAdjust",
|
||||||
"ComputedFontStretchRange",
|
"ComputedFontStretchRange",
|
||||||
"ComputedFontStyleDescriptor",
|
"ComputedFontStyleDescriptor",
|
||||||
"ComputedFontWeightRange",
|
"ComputedFontWeightRange",
|
||||||
|
Loading…
Reference in New Issue
Block a user