Bug 1289007 - part1: parse and compute initial-letter property. r=heycam

MozReview-Commit-ID: E0eXolZ93oJ

--HG--
extra : rebase_source : 3fc74b84a488bb495f926b420aa6c06a987e09b2
This commit is contained in:
Jeremy Chen 2016-07-28 15:23:36 +08:00
Родитель eda421bf9b
Коммит c9f52459aa
12 изменённых файлов: 128 добавлений и 1 удалений

Просмотреть файл

@ -844,6 +844,7 @@ PropertySupportsVariant(nsCSSProperty aPropertyID, uint32_t aVariant)
case eCSSProperty_grid_row_start:
case eCSSProperty_grid_row_end:
case eCSSProperty_font_weight:
case eCSSProperty_initial_letter:
supported = VARIANT_NUMBER;
break;

Просмотреть файл

@ -1004,6 +1004,8 @@ protected:
bool ParseGridArea();
bool ParseGridGap();
bool ParseInitialLetter();
// parsing 'align/justify-items/self' from the css-align spec
bool ParseAlignJustifyPosition(nsCSSValue& aResult,
const KTableEntry aTable[]);
@ -1245,6 +1247,16 @@ protected:
return ParseSingleTokenNonNegativeVariant(aValue, VARIANT_NUMBER, nullptr);
}
// Helpers for some common ParseSingleTokenOneOrLargerVariant calls.
bool ParseOneOrLargerInteger(nsCSSValue& aValue)
{
return ParseSingleTokenOneOrLargerVariant(aValue, VARIANT_INTEGER, nullptr);
}
bool ParseOneOrLargerNumber(nsCSSValue& aValue)
{
return ParseSingleTokenOneOrLargerVariant(aValue, VARIANT_NUMBER, nullptr);
}
// http://dev.w3.org/csswg/css-values/#custom-idents
// Parse an identifier that is none of:
// * a CSS-wide keyword
@ -9779,6 +9791,33 @@ CSSParserImpl::ParseGridGap()
return true;
}
// normal | [<number> <integer>?]
bool
CSSParserImpl::ParseInitialLetter()
{
nsCSSValue value;
// 'inherit', 'initial', 'unset', 'none', and 'normal' must be alone
if (!ParseSingleTokenVariant(value, VARIANT_INHERIT | VARIANT_NORMAL,
nullptr)) {
nsCSSValue first, second;
if (!ParseOneOrLargerNumber(first)) {
return false;
}
if (!ParseOneOrLargerInteger(second)) {
AppendValue(eCSSProperty_initial_letter, first);
return true;
} else {
RefPtr<nsCSSValue::Array> val = nsCSSValue::Array::Create(2);
val->Item(0) = first;
val->Item(1) = second;
value.SetArrayValue(val, eCSSUnit_Array);
}
}
AppendValue(eCSSProperty_initial_letter, value);
return true;
}
// [ $aTable && <overflow-position>? ] ?
// $aTable is for <content-position> or <self-position>
bool
@ -11570,6 +11609,8 @@ CSSParserImpl::ParsePropertyByFunction(nsCSSProperty aPropID)
case eCSSProperty_align_self:
case eCSSProperty_justify_self:
return ParseAlignJustifySelf(aPropID);
case eCSSProperty_initial_letter:
return ParseInitialLetter();
case eCSSProperty_justify_items:
return ParseJustifyItems();
case eCSSProperty_list_style:

Просмотреть файл

@ -2268,6 +2268,17 @@ CSS_PROP_TEXT(
kHyphensKTable,
CSS_PROP_NO_OFFSET,
eStyleAnimType_None)
CSS_PROP_TEXTRESET(
initial-letter,
initial_letter,
InitialLetter,
CSS_PROPERTY_PARSE_FUNCTION |
CSS_PROPERTY_APPLIES_TO_FIRST_LETTER,
"layout.css.initial-letter.enabled",
0,
nullptr,
CSS_PROP_NO_OFFSET,
eStyleAnimType_None)
CSS_PROP_VISIBILITY(
image-orientation,
image_orientation,

Просмотреть файл

@ -3543,6 +3543,25 @@ nsComputedDOMStyle::DoGetImageRegion()
return val.forget();
}
already_AddRefed<CSSValue>
nsComputedDOMStyle::DoGetInitialLetter()
{
const nsStyleTextReset* textReset = StyleTextReset();
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
if (textReset->mInitialLetterSink == 0) {
val->SetIdent(eCSSKeyword_normal);
return val.forget();
} else {
RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false);
val->SetNumber(textReset->mInitialLetterSize);
valueList->AppendCSSValue(val.forget());
RefPtr<nsROCSSPrimitiveValue> second = new nsROCSSPrimitiveValue;
second->SetNumber(textReset->mInitialLetterSink);
valueList->AppendCSSValue(second.forget());
return valueList.forget();
}
}
already_AddRefed<CSSValue>
nsComputedDOMStyle::DoGetLineHeight()
{

Просмотреть файл

@ -404,6 +404,7 @@ private:
already_AddRefed<CSSValue> DoGetImageRegion();
/* Text Properties */
already_AddRefed<CSSValue> DoGetInitialLetter();
already_AddRefed<CSSValue> DoGetLineHeight();
already_AddRefed<CSSValue> DoGetRubyAlign();
already_AddRefed<CSSValue> DoGetRubyPosition();

Просмотреть файл

@ -153,6 +153,7 @@ COMPUTED_STYLE_PROP(height, Height)
COMPUTED_STYLE_PROP(hyphens, Hyphens)
COMPUTED_STYLE_PROP(image_orientation, ImageOrientation)
COMPUTED_STYLE_PROP(ime_mode, IMEMode)
COMPUTED_STYLE_PROP(initial_letter, InitialLetter)
COMPUTED_STYLE_PROP(isolation, Isolation)
COMPUTED_STYLE_PROP(justify_content, JustifyContent)
COMPUTED_STYLE_PROP(justify_items, JustifyItems)

Просмотреть файл

@ -4977,6 +4977,36 @@ nsRuleNode::ComputeTextResetData(void* aStartStruct,
parentText->mUnicodeBidi,
NS_STYLE_UNICODE_BIDI_NORMAL);
// initial-letter: normal, number, array(number, integer?), initial
const nsCSSValue* initialLetterValue = aRuleData->ValueForInitialLetter();
if (initialLetterValue->GetUnit() == eCSSUnit_Null) {
// We don't want to change anything in this case.
} else if (initialLetterValue->GetUnit() == eCSSUnit_Inherit) {
conditions.SetUncacheable();
text->mInitialLetterSink = parentText->mInitialLetterSink;
text->mInitialLetterSize = parentText->mInitialLetterSize;
} else if (initialLetterValue->GetUnit() == eCSSUnit_Initial ||
initialLetterValue->GetUnit() == eCSSUnit_Unset ||
initialLetterValue->GetUnit() == eCSSUnit_Normal) {
// Use invalid values in initial-letter property to mean normal. So we can
// determine whether it is normal by checking mInitialLetterSink == 0.
text->mInitialLetterSink = 0;
text->mInitialLetterSize = 0.0f;
} else if (initialLetterValue->GetUnit() == eCSSUnit_Array) {
const nsCSSValue& firstValue = initialLetterValue->GetArrayValue()->Item(0);
const nsCSSValue& secondValue = initialLetterValue->GetArrayValue()->Item(1);
MOZ_ASSERT(firstValue.GetUnit() == eCSSUnit_Number &&
secondValue.GetUnit() == eCSSUnit_Integer,
"unexpected value unit");
text->mInitialLetterSize = firstValue.GetFloatValue();
text->mInitialLetterSink = secondValue.GetIntValue();
} else if (initialLetterValue->GetUnit() == eCSSUnit_Number) {
text->mInitialLetterSize = initialLetterValue->GetFloatValue();
text->mInitialLetterSink = NSToCoordFloorClamped(text->mInitialLetterSize);
} else {
MOZ_ASSERT_UNREACHABLE("unknown unit for initial-letter");
}
COMPUTE_END_RESET(TextReset, text)
}

Просмотреть файл

@ -3576,6 +3576,8 @@ nsStyleContent::AllocateContents(uint32_t aCount)
nsStyleTextReset::nsStyleTextReset(StyleStructContext aContext)
: mTextDecorationLine(NS_STYLE_TEXT_DECORATION_LINE_NONE)
, mUnicodeBidi(NS_STYLE_UNICODE_BIDI_NORMAL)
, mInitialLetterSink(0)
, mInitialLetterSize(0.0f)
, mTextDecorationStyle(NS_STYLE_TEXT_DECORATION_STYLE_SOLID | BORDER_COLOR_FOREGROUND)
, mTextDecorationColor(NS_RGB(0, 0, 0))
{
@ -3596,7 +3598,9 @@ nsStyleTextReset::~nsStyleTextReset()
nsChangeHint
nsStyleTextReset::CalcDifference(const nsStyleTextReset& aNewData) const
{
if (mUnicodeBidi != aNewData.mUnicodeBidi) {
if (mUnicodeBidi != aNewData.mUnicodeBidi ||
mInitialLetterSink != aNewData.mInitialLetterSink ||
mInitialLetterSize != aNewData.mInitialLetterSize) {
return NS_STYLE_HINT_REFLOW;
}

Просмотреть файл

@ -1977,6 +1977,8 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleTextReset
uint8_t mTextDecorationLine; // [reset] see nsStyleConsts.h
uint8_t mUnicodeBidi; // [reset] see nsStyleConsts.h
nscoord mInitialLetterSink; // [reset] 0 means normal
float mInitialLetterSize; // [reset] 0.0f means normal
protected:
uint8_t mTextDecorationStyle; // [reset] see nsStyleConsts.h

Просмотреть файл

@ -6661,6 +6661,17 @@ if (IsCSSPropertyPrefEnabled("layout.css.image-orientation.enabled")) {
};
}
if (IsCSSPropertyPrefEnabled("layout.css.initial-letter.enabled")) {
gCSSProperties["initial-letter"] = {
domProp: "initialLetter",
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: [ "normal" ],
other_values: [ "2", "2.5", "3.7 2", "4 3" ],
invalid_values: [ "-3", "3.7 -2", "25%", "16px", "1 0", "0", "0 1" ]
};
}
if (IsCSSPropertyPrefEnabled("layout.css.osx-font-smoothing.enabled")) {
gCSSProperties["-moz-osx-font-smoothing"] = {
domProp: "MozOsxFontSmoothing",

Просмотреть файл

@ -2413,6 +2413,9 @@ pref("layout.css.dpi", -1);
// of a CSS "px". This is only used for windows on the screen, not for printing.
pref("layout.css.devPixelsPerPx", "-1.0");
// Is support for CSS initial-letter property enabled?
pref("layout.css.initial-letter.enabled", false);
// Is support for CSS Masking features enabled?
pref("layout.css.masking.enabled", true);

Просмотреть файл

@ -163,6 +163,9 @@ user_pref("layout.css.grid-template-subgrid-value.enabled", true);
// Enable CSS 'contain' for testing
user_pref("layout.css.contain.enabled", true);
// Enable CSS initial-letter for testing
user_pref("layout.css.initial-letter.enabled", true);
// Enable CSS object-fit & object-position for testing
user_pref("layout.css.object-fit-and-position.enabled", true);