Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Problems.GrammaticalOptimization/SharpVectorCss/Css/CssRuleList.cs @ 13918

Last change on this file since 13918 was 12762, checked in by aballeit, 9 years ago

#2283 GUI updates, Tree-chart, MCTS Version 2 (prune leaves)

File size: 8.0 KB
Line 
1// <developer>niklas@protocol7.com</developer>
2// <completed>80</completed>
3
4using System;
5using System.Collections.Generic;
6using System.Text.RegularExpressions;
7using System.Xml;
8using SharpVectors.Dom.Stylesheets;
9
10namespace SharpVectors.Dom.Css
11{
12  /// <summary>
13  /// The CSSRuleList interface provides the abstraction of an ordered collection of CSS rules.
14  /// The items in the CSSRuleList are accessible via an integral index, starting from 0.
15  /// </summary>
16    public sealed class CssRuleList : ICssRuleList
17  {
18    #region Static members
19    /* can take two kind of structures:
20     * rule{}
21     * rule{}
22     * or:
23     * {
24     *  rule{}
25     *  rule{}
26     * }
27     * */
28        private void Parse(ref string css, object parent, bool readOnly, IList<string> replacedStrings, CssStyleSheetType origin)
29    {
30      bool withBrackets = false;
31      css = css.Trim();
32      if(css.StartsWith("{"))
33      {
34        withBrackets = true;
35        css = css.Substring(1);
36      }
37
38      while(true)
39      {
40        css = css.Trim();
41        if(css.Length == 0)
42        {
43          if(withBrackets)
44          {
45            throw new DomException(DomExceptionType.SyntaxErr, "Style block missing ending bracket");
46          }
47          break;
48        }
49        else if(css.StartsWith("}"))
50        {
51          // end of block;
52          css = css.Substring(1);
53          break;
54        }
55        else if(css.StartsWith("@"))
56        {
57          #region Parse at-rules
58          // @-rule
59          CssRule rule;
60
61          // creates and parses a CssMediaRule or return null
62          rule = CssMediaRule.Parse(ref css, parent, readOnly, replacedStrings, origin);
63          if(rule == null)
64          {
65            // create ImportRule
66                        rule = CssImportRule.Parse(ref css, parent, readOnly, replacedStrings, origin);
67
68            if(rule == null)
69            {
70              // create CharSetRule
71              rule = CssCharsetRule.Parse(ref css, parent, readOnly, replacedStrings, origin);
72
73              if(rule == null)
74              {
75                                rule = CssFontFaceRule.Parse(ref css, parent, readOnly, replacedStrings, origin);
76
77                if(rule == null)
78                {
79                                    rule = CssPageRule.Parse(ref css, parent, readOnly, replacedStrings, origin);
80
81                  if(rule == null)
82                  {
83                                        rule = CssUnknownRule.Parse(ref css, parent, readOnly, replacedStrings, origin);
84                  }
85                }
86              }
87            }
88          }
89          InsertRule(rule);
90          #endregion
91        }
92        else
93        {
94          // must be a selector or error
95          CssRule rule = CssStyleRule.Parse(ref css, parent, readOnly, replacedStrings, origin);
96          if(rule != null)
97          {
98            InsertRule(rule);
99          }
100          else
101          {
102                        // this is an unknown rule format, possibly a new kind of selector. Try to find the end of it to skip it
103
104            int startBracket = css.IndexOf("{");
105            int endBracket = css.IndexOf("}");
106            int endSemiColon = css.IndexOf(";");
107            int endRule;
108
109            if(endSemiColon > 0 && endSemiColon < startBracket)
110            {
111              endRule = endSemiColon;
112            }
113            else
114            {
115              endRule = endBracket;
116            }
117
118
119            if(endRule > -1)
120            {
121              css = css.Substring(endRule+1);
122            }
123            else
124            {
125              throw new DomException(DomExceptionType.SyntaxErr, "Can not parse the CSS file");
126            }
127          }
128
129        //}
130        } 
131      }
132    }
133    #endregion
134   
135    #region Constructor
136
137    /// <summary>
138    /// Constructor for CssRuleList
139    /// </summary>
140    /// <param name="parent">The parent rule or parent stylesheet</param>
141    /// <param name="cssText">The CSS text containing the rules that will be in this list</param>
142    /// <param name="replacedStrings">An array of strings that have been replaced in the string used for matching. These needs to be put back use the DereplaceStrings method</param>
143    /// <param name="origin">The type of CssStyleSheet</param>
144    internal CssRuleList(ref string cssText, object parent,
145            IList<string> replacedStrings, CssStyleSheetType origin)
146            : this(ref cssText, parent, replacedStrings, false, origin)
147    {
148    }
149
150    /// <summary>
151    /// Constructor for CssRuleList
152    /// </summary>
153    /// <param name="parent">The parent rule or parent stylesheet</param>
154    /// <param name="cssText">The CSS text containing the rules that will be in this list</param>
155    /// <param name="readOnly">True if this instance is readonly</param>
156    /// <param name="replacedStrings">An array of strings that have been replaced in the string used for matching. These needs to be put back use the DereplaceStrings method</param>
157    /// <param name="origin">The type of CssStyleSheet</param>
158    public CssRuleList(ref string cssText, object parent,
159            IList<string> replacedStrings, bool readOnly, CssStyleSheetType origin)
160    {
161      Origin = origin;
162      ReadOnly = readOnly;
163      if(parent is CssRule || parent is CssStyleSheet)
164      {
165        Parent = parent;
166      }
167      else
168      {
169        throw new Exception("The CssRuleList constructor can only take a CssRule or CssStyleSheet as it's first argument " + parent.GetType());
170      }
171
172      Parse(ref cssText, parent, readOnly, replacedStrings, origin);
173      //AppendRules(cssText, replacedStrings);
174    }
175
176    #endregion
177
178    #region Private fields
179    private CssStyleSheetType Origin;
180    private object Parent;
181        private List<CssRule> cssRules = new List<CssRule>();
182    private bool ReadOnly;
183
184    #endregion
185
186    #region Public methods
187    /// <summary>
188    /// Used to find matching style rules in the cascading order
189    /// </summary>
190    /// <param name="elt">The element to find styles for</param>
191    /// <param name="pseudoElt">The pseudo-element to find styles for</param>
192    /// <param name="ml">The medialist that the document is using</param>
193    /// <param name="csd">A CssStyleDeclaration that holds the collected styles</param>
194    internal void GetStylesForElement(XmlElement elt, string pseudoElt, MediaList ml, CssCollectedStyleDeclaration csd)
195    {
196      ulong len = Length;
197      for(ulong i = 0; i<len; i++)
198      {
199                CssRule csr = (CssRule)this[i];
200        csr.GetStylesForElement(elt, pseudoElt, ml, csd);
201      }
202    }
203
204    internal ulong InsertRule(CssRule rule, ulong index)
205    {
206      /* TODO:
207       * HIERARCHY_REQUEST_ERR: Raised if the rule cannot be inserted at the specified index e.g. if an @import rule is inserted after a standard rule set or other at-rule.
208       * SYNTAX_ERR: Raised if the specified rule has a syntax error and is unparsable
209      */
210     
211      if(ReadOnly) throw new DomException(DomExceptionType.NoModificationAllowedErr);
212     
213      if(index > Length || index<0) throw new DomException(DomExceptionType.IndexSizeErr);
214 
215      if(index == Length)
216      {
217        cssRules.Add(rule);
218      }
219      else
220      {
221        cssRules.Insert((int) index, rule);
222      }
223
224      return index;
225    }
226
227    internal ulong InsertRule(CssRule rule)
228    {
229      return InsertRule(rule, Length);
230    }
231
232   
233    /// <summary>
234    /// Deletes a rule from the list
235    /// </summary>
236    /// <param name="index">The index of the rule to delete</param>
237    /// <exception cref="DomException">NO_MODIFICATION_ALLOWED_ERR</exception>
238    /// <exception cref="DomException">INDEX_SIZE_ERR</exception>
239    internal void DeleteRule(ulong index)
240    {
241      if(ReadOnly) throw new DomException(DomExceptionType.InvalidModificationErr);
242     
243      if(index >= Length || index<0) throw new DomException(DomExceptionType.IndexSizeErr);
244
245      cssRules.RemoveAt((int)index);
246    }
247
248    #endregion
249
250    #region Implementation of ICssRuleList
251    /// <summary>
252    /// The number of CSSRules in the list. The range of valid child rule indices is 0 to length-1 inclusive
253    /// </summary>
254    public ulong Length
255    {
256      get
257      {
258        return (ulong)cssRules.Count;
259      }
260    }
261
262    /// <summary>
263    ///     Used to retrieve a CSS rule by ordinal index. The order in this collection represents the order of the rules in the CSS style sheet. If index is greater than or equal to the number of rules in the list, this returns null
264    /// </summary>
265    public ICssRule this[ulong index]
266    {
267      get
268      {
269        return (index<Length) ? cssRules[(int)index] : null;
270      }
271      set
272      {
273      }
274    }
275    #endregion
276  }
277}
Note: See TracBrowser for help on using the repository browser.