static nsCSSValueList AppendValueToList(ref nsCSSValue aContainer, nsCSSValueList aTail, nsCSSValue aValue) { nsCSSValueList entry; if (aContainer.GetUnit() == nsCSSUnit.Null) { Debug.Assert(aTail == null, "should not have an entry"); entry = aContainer.SetListValue(); } else { Debug.Assert(aTail.mNext == null, "should not have a next entry"); Debug.Assert(aContainer.GetUnit() == nsCSSUnit.List, "not a list"); entry = new nsCSSValueList(); aTail.mNext = entry; } entry.mValue = aValue; return entry; }
/* Parses a transform property list by continuously reading in properties * and constructing a matrix from it. */ bool ParseTransform(bool aIsPrefixed) { var value = new nsCSSValue(); if (ParseVariant(ref value, VARIANT_INHERIT | VARIANT_NONE, null)) { // 'inherit', 'initial', and 'none' must be alone if (!ExpectEndProperty()) { return false; } } else { nsCSSValueList cur = value.SetListValue(); for (;;) { bool is3D = false; if (!ParseSingleTransform(aIsPrefixed, ref cur.mValue, ref is3D)) { return false; } if (is3D && !nsLayoutUtils.Are3DTransformsEnabled()) { return false; } if (CheckEndProperty()) { break; } cur.mNext = new nsCSSValueList(); cur = cur.mNext; } } AppendValue(nsCSSProperty.Transform, value); return true; }
// This function is very similar to ParseBackgroundPosition and // ParseBackgroundSize. internal bool ParseValueList(nsCSSProperty aPropID) { // aPropID is a single value prop-id var value = new nsCSSValue(); if (ParseVariant(ref value, VARIANT_INHERIT, null)) { // 'initial' and 'inherit' stand alone, no list permitted. if (!ExpectEndProperty()) { return false; } } else { nsCSSValueList item = value.SetListValue(); for (;;) { if (!ParseSingleValueProperty(ref item.mValue, aPropID)) { return false; } if (CheckEndProperty()) { break; } if (!ExpectSymbol(',', true)) { return false; } item.mNext = new nsCSSValueList(); item = item.mNext; } } AppendValue(aPropID, value); return true; }
internal void SetBorderImageInitialValues() { // border-image-source: none var source = new nsCSSValue(); source.SetNoneValue(); AppendValue(nsCSSProperty.BorderImageSource, source); // border-image-slice: 100% var sliceBoxValue = new nsCSSValue(); nsCSSRect sliceBox = sliceBoxValue.SetRectValue(); sliceBox.SetAllSidesTo(new nsCSSValue(1.0f, nsCSSUnit.Percent)); var slice = new nsCSSValue(); nsCSSValueList sliceList = slice.SetListValue(); sliceList.mValue = sliceBoxValue; AppendValue(nsCSSProperty.BorderImageSlice, slice); // border-image-width: 1 var width = new nsCSSValue(); nsCSSRect widthBox = width.SetRectValue(); widthBox.SetAllSidesTo(new nsCSSValue(1.0f, nsCSSUnit.Number)); AppendValue(nsCSSProperty.BorderImageWidth, width); // border-image-outset: 0 var outset = new nsCSSValue(); nsCSSRect outsetBox = outset.SetRectValue(); outsetBox.SetAllSidesTo(new nsCSSValue(0.0f, nsCSSUnit.Number)); AppendValue(nsCSSProperty.BorderImageOutset, outset); // border-image-repeat: repeat var repeat = new nsCSSValue(); var repeatPair = new nsCSSValuePair(); repeatPair.SetBothValuesTo(new nsCSSValue(nsStyle.BORDER_IMAGE_REPEAT_STRETCH, nsCSSUnit.Enumerated)); repeat.SetPairValue(repeatPair); AppendValue(nsCSSProperty.BorderImageRepeat, repeat); }
internal bool ParseShadowList(nsCSSProperty aProperty) { using (/*var compound = */new nsAutoParseCompoundProperty(this)) { bool isBoxShadow = aProperty == nsCSSProperty.BoxShadow; var value = new nsCSSValue(); if (ParseVariant(ref value, VARIANT_INHERIT | VARIANT_NONE, null)) { // 'inherit', 'initial', and 'none' must be alone if (!ExpectEndProperty()) { return false; } } else { nsCSSValueList cur = value.SetListValue(); for (;;) { if (!ParseShadowItem(ref cur.mValue, isBoxShadow)) { return false; } if (CheckEndProperty()) { break; } if (!ExpectSymbol(',', true)) { return false; } cur.mNext = new nsCSSValueList(); cur = cur.mNext; } } AppendValue(aProperty, value); return true; } }
internal bool ParseTransitionProperty() { var value = new nsCSSValue(); if (ParseVariant(ref value, VARIANT_INHERIT | VARIANT_NONE, null)) { // 'inherit', 'initial', and 'none' must be alone if (!ExpectEndProperty()) { return false; } } else { // Accept a list of arbitrary identifiers. They should be // CSS properties, but we want to accept any so that we // accept properties that we don't know about yet, e.g. // transition-property: invalid-property, left, opacity; nsCSSValueList cur = value.SetListValue(); for (;;) { if (!ParseVariant(ref cur.mValue, VARIANT_IDENTIFIER | VARIANT_ALL, null)) { return false; } if (cur.mValue.GetUnit() == nsCSSUnit.Ident) { string str = cur.mValue.GetStringBufferValue(); // Exclude 'none' and 'inherit' and 'initial' according to the // same rules as for 'counter-reset' in CSS 2.1. if (str.LowerCaseEqualsLiteral("none") || str.LowerCaseEqualsLiteral("inherit") || str.LowerCaseEqualsLiteral("initial")) { return false; } } if (CheckEndProperty()) { break; } if (!ExpectSymbol(',', true)) { { if (!mSuppressErrors) mReporter.ReportUnexpected("PEExpectedComma", mToken); }; return false; } cur.mNext = new nsCSSValueList(); cur = cur.mNext; } } AppendValue(nsCSSProperty.TransitionProperty, value); return true; }
internal bool ParseCursor() { var value = new nsCSSValue(); if (ParseVariant(ref value, VARIANT_INHERIT, null)) { // 'inherit' and 'initial' must be alone if (!ExpectEndProperty()) { return false; } } else { nsCSSValueList cur = value.SetListValue(); for (;;) { if (!ParseVariant(ref cur.mValue, VARIANT_UK, nsCSSProps.kCursorKTable)) { return false; } if (cur.mValue.GetUnit() != nsCSSUnit.Url) { // keyword must be last if (ExpectEndProperty()) { break; } return false; } // We have a URL, so make a value array with three values. nsCSSValue[] val = new nsCSSValue[3]; val[0] = cur.mValue; // Parse optional x and y position of cursor hotspot (css3-ui). if (ParseVariant(ref val[1], VARIANT_NUMBER, null)) { // If we have one number, we must have two. if (!ParseVariant(ref val[2], VARIANT_NUMBER, null)) { return false; } } cur.mValue.SetArrayValue(val, nsCSSUnit.Array); if (!ExpectSymbol(',', true)) { // url must not be last return false; } cur.mNext = new nsCSSValueList(); cur = cur.mNext; } } AppendValue(nsCSSProperty.Cursor, value); return true; }
internal bool ParseDasharray() { var value = new nsCSSValue(); if (ParseVariant(ref value, VARIANT_HK | VARIANT_NONE, nsCSSProps.kStrokeObjectValueKTable)) { // 'inherit', 'initial', and 'none' are only allowed on their own if (!ExpectEndProperty()) { return false; } } else { nsCSSValueList cur = value.SetListValue(); for (;;) { if (!ParseNonNegativeVariant(ref cur.mValue, VARIANT_LPN, null)) { return false; } if (CheckEndProperty()) { break; } // skip optional commas between elements ExpectSymbol(',', true); cur.mNext = new nsCSSValueList(); cur = cur.mNext; } } AppendValue(nsCSSProperty.StrokeDasharray, value); return true; }
internal bool ParseContent() { // We need to divide the 'content' keywords into two classes for // ParseVariant's sake, so we can't just use nsCSSProps.kContentKTable. /*TODO: static*/ int32_t[] kContentListKWs = { (int32_t)nsCSSKeyword.open_quote, nsStyle.CONTENT_OPEN_QUOTE, (int32_t)nsCSSKeyword.close_quote, nsStyle.CONTENT_CLOSE_QUOTE, (int32_t)nsCSSKeyword.no_open_quote, nsStyle.CONTENT_NO_OPEN_QUOTE, (int32_t)nsCSSKeyword.no_close_quote, nsStyle.CONTENT_NO_CLOSE_QUOTE, (int32_t)nsCSSKeyword.UNKNOWN,-1 }; /*TODO: static*/ int32_t[] kContentSolitaryKWs = { (int32_t)nsCSSKeyword._moz_alt_content, nsStyle.CONTENT_ALT_CONTENT, (int32_t)nsCSSKeyword.UNKNOWN,-1 }; // Verify that these two lists add up to the size of // nsCSSProps.kContentKTable. var value = new nsCSSValue(); if (ParseVariant(ref value, VARIANT_HMK | VARIANT_NONE, kContentSolitaryKWs)) { // 'inherit', 'initial', 'normal', 'none', and 'alt-content' must be alone if (!ExpectEndProperty()) { return false; } } else { nsCSSValueList cur = value.SetListValue(); for (;;) { if (!ParseVariant(ref cur.mValue, VARIANT_CONTENT, kContentListKWs)) { return false; } if (CheckEndProperty()) { break; } cur.mNext = new nsCSSValueList(); cur = cur.mNext; } } AppendValue(nsCSSProperty.Content, value); return true; }
internal bool ParseBorderImageSlice(bool aAcceptsInherit, ref bool? aConsumedTokens) { // border-image-slice: initial | [<number>|<percentage>]{1,4} && fill? var value = new nsCSSValue(); if (aConsumedTokens != null) { aConsumedTokens = true; } if (aAcceptsInherit && ParseVariant(ref value, VARIANT_INHERIT, null)) { // Keyword "inherit" can not be mixed, so we are done. AppendValue(nsCSSProperty.BorderImageSlice, value); return true; } // Try parsing "fill" value. var imageSliceFillValue = new nsCSSValue(); bool hasFill = ParseEnum(ref imageSliceFillValue, nsCSSProps.kBorderImageSliceKTable); // Parse the box dimensions. var imageSliceBoxValue = new nsCSSValue(); if (!ParseGroupedBoxProperty(VARIANT_PN, ref imageSliceBoxValue)) { if (!hasFill && aConsumedTokens != null) { aConsumedTokens = false; } return false; } // Try parsing "fill" keyword again if the first time failed because keyword // and slice dimensions can be in any order. if (!hasFill) { hasFill = ParseEnum(ref imageSliceFillValue, nsCSSProps.kBorderImageSliceKTable); } nsCSSValueList borderImageSlice = value.SetListValue(); // Put the box value into the list. borderImageSlice.mValue = imageSliceBoxValue; if (hasFill) { // Put the "fill" value into the list. borderImageSlice.mNext = new nsCSSValueList(); borderImageSlice.mNext.mValue = imageSliceFillValue; } AppendValue(nsCSSProperty.BorderImageSlice, value); return true; }
internal bool ParseBorderColors(nsCSSProperty aProperty) { var value = new nsCSSValue(); if (ParseVariant(ref value, VARIANT_INHERIT | VARIANT_NONE, null)) { // 'inherit', 'initial', and 'none' are only allowed on their own if (!ExpectEndProperty()) { return false; } } else { nsCSSValueList cur = value.SetListValue(); for (;;) { if (!ParseVariant(ref cur.mValue, VARIANT_COLOR | VARIANT_KEYWORD, nsCSSProps.kBorderColorKTable)) { return false; } if (CheckEndProperty()) { break; } cur.mNext = new nsCSSValueList(); cur = cur.mNext; } } AppendValue(aProperty, value); return true; }
// This function is very similar to ParseBackgroundList and ParseBackgroundSize. internal bool ParseBackgroundPosition() { var value = new nsCSSValue(); if (ParseVariant(ref value, VARIANT_INHERIT, null)) { // 'initial' and 'inherit' stand alone, no list permitted. if (!ExpectEndProperty()) { return false; } } else { var itemValue = new nsCSSValue(); if (!ParseBackgroundPositionValues(ref itemValue, false)) { return false; } nsCSSValueList item = value.SetListValue(); for (;;) { item.mValue = itemValue; if (CheckEndProperty()) { break; } if (!ExpectSymbol(',', true)) { return false; } if (!ParseBackgroundPositionValues(ref itemValue, false)) { return false; } item.mNext = new nsCSSValueList(); item = item.mNext; } } AppendValue(nsCSSProperty.BackgroundPosition, value); return true; }
internal bool ParseBackground() { using (/*var compound = */new nsAutoParseCompoundProperty(this)) { // background-color can only be set once, so it's not a list. var color = new nsCSSValue(); // Check first for inherit/initial. if (ParseVariant(ref color, VARIANT_INHERIT, null)) { // must be alone if (!ExpectEndProperty()) { return false; } AppendValues(nsCSSProps.SubpropertyEntryFor(nsCSSProperty.Background), color); return true; } nsCSSValue image = new nsCSSValue(), repeat = new nsCSSValue(), attachment = new nsCSSValue(), clip = new nsCSSValue(), origin = new nsCSSValue(), position = new nsCSSValue(), size = new nsCSSValue(); var state = new BackgroundParseState(color, image.SetListValue(), repeat.SetPairListValue(), attachment.SetListValue(), clip.SetListValue(), origin.SetListValue(), position.SetListValue(), size.SetPairListValue()); for (;;) { if (!ParseBackgroundItem(state)) { return false; } if (CheckEndProperty()) { break; } // If we saw a color, this must be the last item. if (color.GetUnit() != nsCSSUnit.Null) { { if (!mSuppressErrors) mReporter.ReportUnexpected("PEExpectEndValue", mToken); }; return false; } // Otherwise, a comma is mandatory. if (!ExpectSymbol(',', true)) { return false; } // Chain another entry on all the lists. state.mImage.mNext = new nsCSSValueList(); state.mImage = state.mImage.mNext; state.mRepeat.mNext = new nsCSSValuePairList(); state.mRepeat = state.mRepeat.mNext; state.mAttachment.mNext = new nsCSSValueList(); state.mAttachment = state.mAttachment.mNext; state.mClip.mNext = new nsCSSValueList(); state.mClip = state.mClip.mNext; state.mOrigin.mNext = new nsCSSValueList(); state.mOrigin = state.mOrigin.mNext; state.mPosition.mNext = new nsCSSValueList(); state.mPosition = state.mPosition.mNext; state.mSize.mNext = new nsCSSValuePairList(); state.mSize = state.mSize.mNext; } // If we get to this point without seeing a color, provide a default. if (color.GetUnit() == nsCSSUnit.Null) { color.SetColorValue(nscolor.RGBA(0,0,0,0)); } AppendValue(nsCSSProperty.BackgroundImage, image); AppendValue(nsCSSProperty.BackgroundRepeat, repeat); AppendValue(nsCSSProperty.BackgroundAttachment, attachment); AppendValue(nsCSSProperty.BackgroundClip, clip); AppendValue(nsCSSProperty.BackgroundOrigin, origin); AppendValue(nsCSSProperty.BackgroundPosition, position); AppendValue(nsCSSProperty.BackgroundSize, size); AppendValue(nsCSSProperty.BackgroundColor, color); return true; } }