Пример #1
0
        /// <summary>Gets or sets the parsed value of this style by property name.</summary>
        /// <param name="property">The property to get the value for.</param>
        public Value this[string cssProperty] {
            get{
                // Get the property:
                CssProperty property = CssProperties.Get(cssProperty);

                if (property == null)
                {
                    return(null);
                }

                return(this[property]);
            }

            set{
                // Get the CSS property:
                CssProperty property = CssProperties.Get(cssProperty);

                if (property == null)
                {
                    return;
                }

                this[property] = value;
            }
        }
Пример #2
0
        /// <summary>
        /// Adds all the type checkers to the given scanner.
        /// They basically automatically find CSS properties, units etc in assemblies.
        /// </summary>
        public static void AddToScanner(Modular.AssemblyScanner scanner)
        {
            // CSS functions:
            scanner.FindAllSubTypes(typeof(CssFunction), delegate(Type type){
                // Add it:
                CssFunctions.Add(type);
            });

            // CSS at rules:
            scanner.FindAllSubTypes(typeof(CssAtRule), delegate(Type type){
                // Add it:
                CssAtRules.Add(type);
            });

            // CSS units:
            scanner.FindAllSubTypes(typeof(CssUnit), delegate(Type type){
                // Add it:
                CssUnits.Add(type);
            });

            // CSS keywords:
            scanner.FindAllSubTypes(typeof(CssKeyword), delegate(Type type){
                // Add it:
                CssKeywords.Add(type);
            });

            // CSS properties (secondary pass; requires default values which can be any of the above):
            scanner.FindAllSubTypes(1, typeof(CssProperty), delegate(Type type){
                // Add it:
                CssProperties.Add(type);
            });
        }
Пример #3
0
        /// <summary>Sets the named property on this style to the given value.</summary>
        /// <param name="cssProperty">The property to set or overwrite. e.g. "display".</param>
        /// <param name="value">The value to set the property to, e.g. "none".</param>
        public Css.Value Set(string cssProperty, string valueText)
        {
            cssProperty = cssProperty.Trim().ToLower();

            // Get the property:
            CssProperty property = CssProperties.Get(cssProperty);

            if (property == null)
            {
                // Property not found:
                return(null);
            }

            // The underlying value:
            Css.Value value;

            if (string.IsNullOrEmpty(valueText))
            {
                // No value - actually a clear:
                value = null;
            }
            else
            {
                // Create a lexer for the value:
                CssLexer lexer = new CssLexer(valueText, Element);

                // Read the underlying value:
                value = lexer.ReadValue();
            }

            // Apply, taking aliases into account:
            this[property] = value;

            return(value);
        }
Пример #4
0
        /// <summary>This is called to change a CSS property from an element.
        /// For example, font color=".." uses this. It sets a specifity of 0 as required by
        /// https://www.w3.org/TR/CSS2/cascade.html 6.4.4</summary>
        /// <param name="cssProperty">The css property being changed.</param>
        /// <param name="newValue">The new property value.</param>
        public void ChangeTagProperty(string cssProperty, Css.Value newValue)
        {
            // Resolve the property:
            CssProperty property = CssProperties.Get(cssProperty);

            if (property == null)
            {
                return;
            }

            // Apply now:
            ChangeProperty(property, newValue);
        }
Пример #5
0
        /// <summary>This is called to change a CSS property from an element.
        /// For example, font color=".." uses this. It sets a specifity of 0 as required by
        /// https://www.w3.org/TR/CSS2/cascade.html 6.4.4</summary>
        /// <param name="cssProperty">The css property being changed.</param>
        /// <param name="newValue">The new property value.</param>
        public Css.Value ChangeTagProperty(string cssProperty, string newValue)
        {
            // Resolve the property:
            CssProperty property = CssProperties.Get(cssProperty);

            if (property == null)
            {
                return(null);
            }

            Css.Value val = Css.Value.Load(newValue);

            // Apply now:
            ChangeProperty(property, val);

            return(val);
        }
Пример #6
0
        /// <summary>Sets a property from a composite set. Any new values that are null are set to the initial value
        /// and inherit the specifity from the composite value.</summary>
        public void SetComposite(string cssProperty, Css.Value newValue, Css.Value composite)
        {
            // Get the property:
            CssProperty property = CssProperties.Get(cssProperty);

            if (property == null)
            {
                return;
            }

            if (newValue == null && composite != null)
            {
                // Use the specifity in the comps value:
                newValue = new Css.Keywords.Initial(property, composite.Specifity);
            }

            // Write it now:
            this[property] = newValue;
        }
Пример #7
0
        /// <summary>Causes the named property to apply its value.</summary>
        public void Reapply(ComputedStyle computed, string propertyName)
        {
            // Get the property:
            CssProperty property = CssProperties.Get(propertyName);

            if (property == null)
            {
                return;
            }

            // Got a value?
            Value value = computed[property];

            if (value == null)
            {
                return;
            }

            // Apply:
            property.Apply(computed, value);
        }
Пример #8
0
        /// <summary>This is called to change a CSS property from an element.
        /// For example, font color=".." uses this. It sets a specifity of 0 as required by
        /// https://www.w3.org/TR/CSS2/cascade.html 6.4.4</summary>
        /// <param name="cssProperty">The css property being changed.</param>
        /// <param name="newValue">The new property value.</param>
        public void ChangeTagProperty(string cssProperty, Css.Value newValue, bool requestLayout)
        {
            // Resolve the property:
            CssProperty property = CssProperties.Get(cssProperty);

            if (property == null)
            {
                return;
            }

            Renderman rm = (Element.document as Css.ReflowDocument).Renderer;

            bool layoutState = rm.DoLayout;

            // Apply now:
            ChangeProperty(property, newValue);

            // Restore layout state:
            if (!requestLayout)
            {
                rm.DoLayout = layoutState;
            }
        }
Пример #9
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;
                }
            }
        }