///////////////////////////////////////////////////////////////////////////////// #region 解析 Token ///////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> protected void ResolveTokens() { System.Diagnostics.Debug.Assert(m_result != null); int visitor = 0; List <DCssSelector> selectorList = new List <DCssSelector>(); while (visitor < m_tokens.Count) { StyleSheetToken token = m_tokens[visitor]; //=====================================================================================// if (token.Type == StyleSheetToken.TokenType.Selector) { selectorList.Add(ResolveSelector(m_tokens[visitor].Content)); ++visitor; } //=====================================================================================// else if (token.Type == StyleSheetToken.TokenType.PropertyList) { System.Diagnostics.Debug.Assert(selectorList.Count > 0); DCssSelector selector = selectorList[0]; ResolvePropertyList(m_tokens[visitor].Content, selector.Properties); ++visitor; for (int index = 1; index < selectorList.Count; ++index) { DCssSelector cloneSelector = selectorList[index]; int propertyCount = selector.Properties.Count; for (int propertyIndex = 0; propertyIndex < propertyCount; ++propertyIndex) { cloneSelector.Properties.AddLast((DCssProperty)selector.Properties[propertyIndex].Clone()); } } m_result.AddRange(selectorList); selectorList.Clear(); } else { System.Diagnostics.Debug.Assert(false); } } m_tokens.Clear(); }
///////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /// <param name="input"></param> /// <returns></returns> public DCssSelector ResolveSelector(string input) { System.Diagnostics.Debug.Assert(input != null); DCssSelector selector = new DCssSelector(); string[] selectorList = input.Split(CHtmlUtil.WhiteSpaceCharsArray); StringBuilder builder = new StringBuilder(); bool combinatorExist = false; for (int tokenIndex = 0, count = selectorList.Length; tokenIndex < count; ++tokenIndex) { string token = selectorList[tokenIndex]; if (token.Equals('+')) // combinator + { if (selector.Count != 0 && combinatorExist == false) { selector[selector.Count - 1].Combinator = DCssSimpleSelector.Relation.Sibling; combinatorExist = true; } else { throw new ParseExeception(); } } else if (token.Equals('>')) // combinator > { if (selector.Count != 0 && combinatorExist == false) { selector[selector.Count - 1].Combinator = DCssSimpleSelector.Relation.Child; combinatorExist = true; } else { throw new ParseExeception(); } } else { DCssSimpleSelector simpleSelector = new DCssSimpleSelector(); builder.Length = 0; int index = 0; while (index < token.Length) { if (token[index].Equals('#')) // id { index += 1; if (index >= token.Length) { throw new ParseExeception(); } int nextIndex = token.IndexOfAny("#.:[".ToCharArray(), index); if (nextIndex != -1) { simpleSelector.ID = token.Substring(index, nextIndex - index); index = nextIndex; } else { simpleSelector.ID = token.Substring(index); index = token.Length; } } else if (token[index].Equals('.')) // class { index += 1; if (index >= token.Length) { throw new ParseExeception(); } int nextIndex = token.IndexOfAny("#.:[".ToCharArray(), index); if (nextIndex != -1) { simpleSelector.Class = token.Substring(index, nextIndex - index); index = nextIndex; } else { simpleSelector.Class = token.Substring(index); index = token.Length; } } else if (token[index].Equals('[')) // attribute { System.Diagnostics.Debug.Assert(false); } else if (token[index].Equals(':')) // pseudo-x { index += 1; if (index >= token.Length) { throw new ParseExeception(); } int nextIndex = token.IndexOfAny("#.:[".ToCharArray(), index); if (nextIndex != -1) { simpleSelector.Pseudo = token.Substring(index, nextIndex - index); index = nextIndex; } else { simpleSelector.Pseudo = token.Substring(index); index = token.Length; } } else // element name { int nextIndex = token.IndexOfAny("#.[:".ToCharArray(), index); if (nextIndex != -1) { simpleSelector.ElementNames = token.Substring(index, nextIndex - index); index = nextIndex; } else { simpleSelector.ElementNames = token.Substring(index); index = token.Length; } } } selector.Add(simpleSelector); combinatorExist = false; } } return(selector); }