예제 #1
0
        /// <summary>Keeps reading selectors and their properties until a &gt; or the end of the css is reached.</summary>
        /// <param name="css">The css text to parse.</param>
        public void ParseCss(string css)
        {
            CssLexer lexer = new CssLexer(css, ownerNode);

            lexer.Sheet = this;

            while (lexer.Peek() != '\0')
            {
                // Read a selector block:
                Rule[] set;
                Rule   rule = lexer.ReadRules(out set);

                // Add:
                Add(rule, set, true);

                // Skip any junk.
                // This is done down here too to avoid creating a blank selector.
                lexer.SkipJunk();
            }
        }
예제 #2
0
        /// <summary>Reads the properties for this style block from the lexer.
        /// Essentially treats it like a set of properties only. Terminated by }, null or &gt;.</summary>
        public void LoadProperties(CssLexer lexer, OnReadProperty onPropertyRead)
        {
            // Read the properties inside a selectors block.
            lexer.SkipJunk();

            char current = lexer.Peek();

            bool readPropertyName = true;
            bool isVariable       = false;
            int  dashCount        = 0;

            StringBuilder propertyName = new StringBuilder();

            while (current != '\0' && current != '<' && current != '}')
            {
                // Read the property name:
                if (readPropertyName)
                {
                    // Hash, open quote or {? If so, the value does not start with a colon.
                    CssUnitHandlers set;
                    if (CssUnits.AllStart.TryGetValue(current, out set))
                    {
                        // Match on the pretext:
                        Value value = set.Handle(lexer, false);

                        if (value != null)
                        {
                            // Read the value (using the global instance):
                            value = value.ReadStartValue(lexer);

                            // Call ready:
                            value.OnValueReady(lexer);

                            // Get the property name:
                            string pName = propertyName.ToString().ToLower().Trim();
                            propertyName.Length = 0;

                            // Trigger OPR (note that it's triggered all the time):
                            int status = 0;

                            if (onPropertyRead != null)
                            {
                                status = onPropertyRead(this, pName, value);
                            }

                            if (status == 0)
                            {
                                // Map property to a function:
                                CssProperty property = CssProperties.Get(pName);

                                if (property != null)
                                {
                                    // Apply, taking aliases into account:
                                    property.OnReadValue(this, value);
                                }
                            }

                            // Read off any junk:
                            lexer.SkipJunk();

                            // Update current:
                            current = lexer.Peek();

                            continue;
                        }
                    }

                    if (current == ':')
                    {
                        // Done reading the property:
                        readPropertyName = false;
                        dashCount        = 0;

                        // Note that we don't need to skip junk as ReadValue will internally anyway.
                    }
                    else if (current == '-' && propertyName.Length == 0)
                    {
                        dashCount++;

                        if (dashCount == 2)
                        {
                            isVariable          = true;
                            propertyName.Length = 0;
                        }
                        else
                        {
                            propertyName.Append(current);
                        }
                    }
                    else
                    {
                        propertyName.Append(current);
                    }

                    // Read it off:
                    lexer.Read();

                    // And take a look at what's next:
                    current = lexer.Peek();
                }
                else
                {
                    // Read the value:
                    Value value = lexer.ReadValue();

                    string pName = propertyName.ToString().ToLower().Trim();
                    propertyName.Length = 0;

                    if (isVariable)
                    {
                        // CSS variable.
                        isVariable = false;

                        // Add to lexer set:
                        lexer.AddVariable(pName, value);
                    }
                    else
                    {
                        // Trigger OPR (note that it's triggered all the time):
                        int status = 0;

                        if (onPropertyRead != null)
                        {
                            status = onPropertyRead(this, pName, value);
                        }

                        if (status == 0)
                        {
                            // Map property to a function:
                            CssProperty property = CssProperties.Get(pName);

                            if (property != null)
                            {
                                // Apply, taking aliases into account:
                                property.OnReadValue(this, value);
                            }
                        }
                    }

                    // ReadValue might actually read off the } in malformed CSS.
                    // Make sure it didn't just do that:
                    if (lexer.Input[lexer.Position - 1] == '}')
                    {
                        lexer.Position--;
                    }

                    // Read off any junk:
                    lexer.SkipJunk();

                    // Update current:
                    current = lexer.Peek();

                    // Go into property reading mode:
                    readPropertyName = true;
                }
            }
        }