/// <summary> /// Creates a new style rule from the given source. /// </summary> /// <param name="source">The token iterator.</param> /// <returns>The style rule.</returns> CSSStyleRule CreateStyleRule(IEnumerator <CssToken> source) { var style = new CSSStyleRule(); var ctor = new CssSelectorConstructor(); ctor.IgnoreErrors = ignore; style.ParentStyleSheet = sheet; style.ParentRule = CurrentRule; open.Push(style); do { if (source.Current.Type == CssTokenType.CurlyBracketOpen) { if (SkipToNextNonWhitespace(source)) { var tokens = LimitToCurrentBlock(source); AppendDeclarations(tokens.GetEnumerator(), style.Style.List); } break; } ctor.PickSelector(source); }while (source.MoveNext()); style.Selector = ctor.Result; open.Pop(); return(style); }
public static CSSStyleRule ConvertToCSSStyleRule(AntlrModel.RuleSet ruleset) { var rule = new CSSStyleRule(); rule.cssText = ruleset.Serialize(); foreach (var selector in ruleset.Selectors) { if (selector.SimpleSelector != null) { rule.selectors.Add(new simpleSelector() { Type = (enumSimpleSelectorType)selector.SimpleSelector.GetSelectorType(), wholeText = selector.SimpleSelector.Serialize() }); } if (selector.CombinationSelectors != null && selector.CombinationSelectors.Count != 0) { foreach (var cs in selector.CombinationSelectors) { rule.selectors.Add(new simpleSelector() { Type = enumSimpleSelectorType.combinator, wholeText = cs.Serialize() }); } } } return(rule); }
/// <summary> /// From W3C, in most case, th preclude matchs to Selector and block value contains declaration. /// </summary> /// <param name="rule"></param> /// <returns></returns> private static CSSRule ParseQualifiedRule(QualifiedRule rule, ref string OriginalCss) { CSSStyleRule cssrule = new CSSStyleRule(); string selectorText = string.Empty; int startindex = -1; int endindex = -1; int endindexselector = -1; selectorText = ComponentValueExtension.getString(rule.prelude, ref startindex, ref endindexselector, ref OriginalCss); cssrule.selectorText = selectorText; cssrule.style = ParseDeclarations(rule.block, ref endindex, ref OriginalCss); cssrule.StartIndex = rule.startindex; cssrule.EndIndex = rule.endindex; cssrule.EndSelectorIndex = endindexselector - cssrule.StartIndex + 1; return(cssrule); }
public static List <CssConvertResult> ConvertCss(CSSRuleList rulelist, Guid ParentStyleId, Guid ParentCssRuleId = default(Guid)) { List <CssConvertResult> Result = new List <CssConvertResult>(); int counter = rulelist.item.Count; for (int i = 0; i < counter; i++) { CmsCssRule cmsrule = new CmsCssRule(); cmsrule.ParentCssRuleId = ParentCssRuleId; cmsrule.ParentStyleId = ParentStyleId; cmsrule.OwnerObjectId = ParentStyleId; cmsrule.OwnerObjectConstType = ConstObjectType.Style; cmsrule.TempCssRuleIndex = i; CSSRule item = rulelist.item[i]; cmsrule.selectorPositionIndex = item.EndSelectorIndex; if (item.type == enumCSSRuleType.STYLE_RULE) { CSSStyleRule stylerule = item as CSSStyleRule; cmsrule.CssText = stylerule.cssText; cmsrule.ruleType = RuleType.StyleRule; cmsrule.Properties = stylerule.style.item.Where(o => o != null && !string.IsNullOrWhiteSpace(o.propertyname)).Select(o => o.propertyname).ToList(); } else if (item.type == enumCSSRuleType.IMPORT_RULE) { CSSImportRule importrule = item as CSSImportRule; cmsrule.CssText = importrule.cssText; cmsrule.ruleType = RuleType.ImportRule; } else if (item.type == enumCSSRuleType.MEDIA_RULE) { CSSMediaRule mediarule = item as CSSMediaRule; cmsrule.CssText = mediarule.cssText; cmsrule.ruleType = RuleType.MediaRule; } else if (item.type == enumCSSRuleType.FONT_FACE_RULE) { CSSFontFaceRule facerule = item as CSSFontFaceRule; cmsrule.CssText = facerule.cssText; cmsrule.ruleType = RuleType.FontFaceRule; } else { continue; } /// check duplicate in the current collections. cmsrule.DuplicateIndex = CssService.GetDuplicateIndex(Result, cmsrule.SelectorText, cmsrule.ruleType); CssConvertResult converted = new CssConvertResult(); converted.RuleId = cmsrule.Id; converted.CmsRule = cmsrule; converted.CssRule = item; Result.Add(converted); if (item.type == enumCSSRuleType.MEDIA_RULE) { var mediarule = item as Kooboo.Dom.CSS.CSSMediaRule; var sub = ConvertCss(mediarule.cssRules, ParentStyleId, cmsrule.Id); if (sub != null && sub.Count() > 0) { Result.AddRange(sub); } } } return(Result); }
/// <summary> /// consume a list of cssrule from simpleblock, /// Recursive. /// </summary> /// <param name="block"></param> /// <returns></returns> private static CSSRuleList ParseMediaRuleList(SimpleBlock block, ref int endindex, CSSMediaRule parentmediarule, ref string OriginalCss) { int count = block.value.Count; CSSRuleList rulelist = new CSSRuleList(); MediaRuleParseState state = MediaRuleParseState.init; CSSStyleRule stylerule = null; CSSMediaRule mediarule = null; string media = string.Empty; string wholeconditiontext = string.Empty; int startindex = -1; for (int i = 0; i < count; i++) { if (block.value[i].endindex > endindex) { endindex = block.value[i].endindex; } if (startindex < 0) { startindex = block.value[i].startindex; } switch (state) { case MediaRuleParseState.init: { if (block.value[i].Type == CompoenentValueType.preservedToken) { PreservedToken pretoken = block.value[i] as PreservedToken; if (pretoken.token.Type == enumTokenType.whitespace) { // ignored whitespace at the beginning. } else if (pretoken.token.Type == enumTokenType.at_keyword) { // at keyword token, only handle media now. // others to be added. at_keyword_token token = pretoken.token as at_keyword_token; if (token.value.ToLower() == "media") { state = MediaRuleParseState.mediarule; i = i - 1; // reconsume to have correct startindex. } else { // other at rules. state = MediaRuleParseState.OtherAtRule; i = i - 1; } } /// else treat as regular style rule. else { state = MediaRuleParseState.stylerule; i = i - 1; // reconsume. } } break; } case MediaRuleParseState.stylerule: { if (stylerule == null) { stylerule = new CSSStyleRule(); startindex = block.value[i].startindex; } if (block.value[i].Type == CompoenentValueType.preservedToken) { PreservedToken pretoken = block.value[i] as PreservedToken; // not a defined way to parse the selector, assembly them back and give it to selector module. // in the new way of getting selectorText, we have not need to assign it any more. //stylerule.selectorText += pretoken.token.getString(); } else if (block.value[i].Type == CompoenentValueType.simpleBlock) { int endselectorindex = block.value[i].startindex; stylerule.style = ParseDeclarations(block.value[i] as SimpleBlock, ref endindex, ref OriginalCss); stylerule.StartIndex = startindex; stylerule.EndIndex = endindex; stylerule.EndSelectorIndex = endselectorindex - stylerule.StartIndex; stylerule.parentRule = parentmediarule; stylerule.parentStyleSheet = parentmediarule.parentStyleSheet; rulelist.appendRule(stylerule); stylerule = null; state = MediaRuleParseState.init; startindex = -1; } break; } case MediaRuleParseState.mediarule: { if (mediarule == null) { mediarule = new CSSMediaRule(); media = string.Empty; wholeconditiontext = string.Empty; startindex = block.value[i].startindex; mediarule.parentStyleSheet = parentmediarule.parentStyleSheet; mediarule.parentRule = parentmediarule; } if (block.value[i].Type == CompoenentValueType.preservedToken) { PreservedToken pretoken = block.value[i] as PreservedToken; if (pretoken.token.Type == enumTokenType.comma) { if (!string.IsNullOrEmpty(media)) { mediarule.media.appendMedium(media.Trim()); media = string.Empty; } wholeconditiontext += ","; } else { // can be delim token. if (string.IsNullOrEmpty(media) && pretoken.token.Type == enumTokenType.whitespace) { // the start of whitespace will be ignored. } else { media += pretoken.token.GetString(ref OriginalCss); wholeconditiontext += pretoken.token.GetString(ref OriginalCss); } } } else if (block.value[i].Type == CompoenentValueType.simpleBlock) { CSSRuleList mediarulelist = ParseMediaRuleList(block.value[i] as SimpleBlock, ref endindex, mediarule, ref OriginalCss); mediarule.cssRules = mediarulelist; if (!string.IsNullOrEmpty(media)) { mediarule.media.appendMedium(media.Trim()); wholeconditiontext += media; } mediarule.conditionText = wholeconditiontext; mediarule.selectorText = wholeconditiontext; /// NON-W3C. mediarule.StartIndex = startindex; mediarule.EndIndex = endindex; rulelist.appendRule(mediarule); state = 0; mediarule = null; media = string.Empty; wholeconditiontext = string.Empty; startindex = -1; } break; } case MediaRuleParseState.OtherAtRule: { //if (mediarule == null) //{ // mediarule = new CSSMediaRule(); // media = string.Empty; // wholeconditiontext = string.Empty; // startindex = block.value[i].startindex; // mediarule.parentStyleSheet = parentmediarule.parentStyleSheet; // mediarule.parentRule = parentmediarule; //} if (block.value[i].Type == CompoenentValueType.preservedToken) { //PreservedToken pretoken = block.value[i] as PreservedToken; //if (pretoken.token.Type == enumTokenType.comma) //{ // if (!string.IsNullOrEmpty(media)) // { // mediarule.media.appendMedium(media.Trim()); // media = string.Empty; // } // wholeconditiontext += ","; //} //else //{ // // can be delim token. // if (string.IsNullOrEmpty(media) && pretoken.token.Type == enumTokenType.whitespace) // { // // the start of whitespace will be ignored. // } // else // { // media += pretoken.token.GetString(ref OriginalCss); // wholeconditiontext += pretoken.token.GetString(ref OriginalCss); // } //} } else if (block.value[i].Type == CompoenentValueType.simpleBlock) { // not implemented now. //CSSRuleList mediarulelist = ParseMediaRuleList(block.value[i] as SimpleBlock, ref endindex, mediarule, ref OriginalCss); //mediarule.cssRules = mediarulelist; //if (!string.IsNullOrEmpty(media)) //{ // mediarule.media.appendMedium(media.Trim()); // wholeconditiontext += media; //} //mediarule.conditionText = wholeconditiontext; //mediarule.selectorText = wholeconditiontext; /// NON-W3C. //mediarule.StartIndex = startindex; //mediarule.EndIndex = endindex; //rulelist.appendRule(mediarule); state = MediaRuleParseState.init; startindex = -1; } break; } default: break; } } if (stylerule != null) { if (stylerule.EndIndex > stylerule.StartIndex) { rulelist.appendRule(stylerule); } stylerule = null; } if (mediarule != null) { rulelist.appendRule(mediarule); mediarule = null; } return(rulelist); }