Пример #1
0
        /// <summary>Removes this selector from its parent documents caches.</summary>
        public void RemoveFromDocument(StyleRule rule, ReflowDocument document, Css.StyleSheet sheet)
        {
            // Get the cached root name:
            string text = LastRoot.StyleText;

            List <StyleRule> list = null;

            if (text == "*")
            {
                list = document.AnySelectors;
            }
            else
            {
                // Add the rule:
                document.SelectorStubs.TryGetValue(text, out list);
            }

            // Remove from the set:
            if (list != null)
            {
                for (int i = 0; i < list.Count; i++)
                {
                    if (list[i] == rule)
                    {
                        list.RemoveAt(i);
                        break;
                    }
                }
            }

            // For each root, remove their locals:
            for (int r = 0; r < RootCount; r++)
            {
                // Get locals set:
                LocalMatcher[] locals = Roots[r].LocalMatchers;

                if (locals != null)
                {
                    // For each one..
                    for (int i = 0; i < locals.Length; i++)
                    {
                        // Remove it:
                        locals[i].RemoveFromDocument(document, sheet);
                    }
                }
            }
        }
        internal void BuildString(Css.StyleSheet sheet)
        {
            string result = "";

            foreach (Css.Rule rule in sheet.rules)
            {
                Css.StyleRule style = rule as Css.StyleRule;

                if (style == null)
                {
                    result += rule.GetType() + "\r\n";
                }
                else
                {
                    result += style.Selector.ToString() + "\r\n";
                }
            }

            ComputedNodeData = result;
        }
Пример #3
0
        /// <summary>Adds this selector to its parent documents caches.
        /// This is used by the default style sheet when the document gets cleared.</summary>
        public void AddToDocument(StyleRule rule, ReflowDocument document, Css.StyleSheet sheet)
        {
            // Get the cached root (always the 'last' one):
            string text = LastRoot.StyleText;

            List <StyleRule> list = null;

            if (text == "*")
            {
                list = document.AnySelectors;
            }
            else
            {
                // Add the rule:
                if (!document.SelectorStubs.TryGetValue(text, out list))
                {
                    list = new List <StyleRule>();
                    document.SelectorStubs[text] = list;
                }
            }

            // Add the rule to the set:
            list.Add(rule);

            // For each root, add their locals:
            for (int r = 0; r < RootCount; r++)
            {
                // Get locals set:
                LocalMatcher[] locals = Roots[r].LocalMatchers;

                if (locals != null)
                {
                    // For each one..
                    for (int i = 0; i < locals.Length; i++)
                    {
                        // Add it:
                        locals[i].AddToDocument(document, sheet);
                    }
                }
            }
        }
Пример #4
0
        public KeyframesRule(StyleSheet sheet, Css.Value rawValue, string name, List <Rule> frames)
        {
            Name        = name;
            ParentSheet = sheet;
            RawValue    = rawValue;

            SortedDictionary <float, KeyframesKeyframe> sortedSet = new SortedDictionary <float, KeyframesKeyframe>();

            // Sort the set by % order. Exceptions for from and to.
            foreach (Rule rule in frames)
            {
                StyleRule styleRule = rule as StyleRule;

                if (styleRule == null)
                {
                    continue;
                }

                // Create the frame:
                KeyframesKeyframe frame = new KeyframesKeyframe(styleRule.Style);

                if (frame.Style == null)
                {
                    // Empty keyframe - ignore it.
                    continue;
                }

                // What is its percentage position?
                Css.Value cssValue = styleRule.Selector.Value[0];

                float percF = 0f;

                if (cssValue.Type == ValueType.Text)
                {
                    // Get as text:
                    string text = cssValue.Text.ToLower();

                    if (text == "from")
                    {
                        percF = 0f;
                    }
                    else if (text == "to")
                    {
                        percF = 1f;
                    }
                    else
                    {
                        continue;
                    }
                }
                else
                {
                    percF = cssValue.GetRawDecimal() / 100f;
                }

                // Apply the time:
                frame.Time = percF;

                // Add to Frames set in order of percF.
                sortedSet[percF] = frame;
            }

            // Create the frames set:
            FrameCount = sortedSet.Count;
            Frames     = new KeyframesKeyframe[FrameCount];
            int index = 0;

            foreach (KeyValuePair <float, KeyframesKeyframe> kvp in sortedSet)
            {
                if (index != 0)
                {
                    // Get the frame before:
                    KeyframesKeyframe before = Frames[index - 1];

                    // Figure out the gap between them:
                    float delay = kvp.Value.Time - before.Time;

                    // Update the delay that occurs after it:
                    before.AfterDelay = delay;

                    // And update the delay that occurs before this:
                    kvp.Value.BeforeDelay = delay;
                }
                else
                {
                    // Apply before:
                    kvp.Value.BeforeDelay = kvp.Value.Time;
                }

                Frames[index] = kvp.Value;
                index++;
            }
        }
Пример #5
0
        /// <summary>Converts a value to a rule. Note that it can be a set of rules (RuleSet).</summary>
        public static Rule ConvertToRule(Rule parentRule, Css.Value value, StyleSheet sheet, out Rule[] ruleSet)
        {
            ruleSet = null;

            if (value == null)
            {
                // Nothing else.
                return(null);
            }

            // Is it an @ rule? Note that they can actually be 'nested' inside an,array,of,selectors (happens with @media)
            AtRuleUnit atRule = value[0] as AtRuleUnit;

            if (atRule != null)
            {
                // Let the @ rule handle the value:
                return(atRule.AtRule.LoadRule(parentRule, sheet, value));
            }

            // One or more selectors followed by a block unit.
            // Get the block:
            int max = value.Count - 1;

            SelectorBlockUnit block = value[max] as SelectorBlockUnit;

            if (block == null)
            {
                // Try as a set instead:
                ValueSet set = value[max] as ValueSet;

                if (set == null)
                {
                    // Invalid/ unrecognised selector block. Ignore it.
                    return(null);
                }

                // Get last one in the set:
                block = set[set.Count - 1] as SelectorBlockUnit;

                // still null?
                if (block == null)
                {
                    // Invalid/ unrecognised selector block. Ignore it.
                    return(null);
                }

                // Check again for an @rule:
                Css.Value v0 = value[0];

                if (v0 != null && v0[0] is AtRuleUnit)
                {
                    // Got an at rule!
                    atRule = v0[0] as AtRuleUnit;

                    return(atRule.AtRule.LoadRule(parentRule, sheet, value));
                }

                // Clear last one:
                set[set.Count - 1] = null;
            }
            else
            {
                // Clear the block from the value:
                value[max] = null;
            }

            // Get the style object:
            Style style = block.Style;

            // Read the selector(s):
            List <Selector> into = new List <Selector>();

            ReadSelectors(sheet, value, into);

            if (into.Count == 0)
            {
                return(null);
            }

            if (into.Count != 1)
            {
                ruleSet = new Rule[into.Count];
            }

            // Got a specifity override? -spark-specifity:x
            Css.Value specifityOverride = null;
            int       specOverride      = -1;

            if (style.Properties.TryGetValue(Css.Properties.SparkSpecifity.GlobalProperty, out specifityOverride))
            {
                // Yep! Pull the integer value:
                specOverride = specifityOverride.GetInteger(null, null);
            }

            for (int i = 0; i < into.Count; i++)
            {
                // Get it:
                Selector s = into[i];

                // Create the rule:
                StyleRule rule = new StyleRule(style);
                rule.ParentStyleSheet = sheet;
                rule.Selector         = s;
                s.Rule = rule;

                // Must use a copy of the style if its a secondary selector.
                // This is because the 'specifity' of CSS properties is defined by how specific
                // a selector is. So, when there's multiple selectors, we have to clone the style.

                Style currentStyle = i == 0?style:style.Clone();

                // Apply the selectors specifity to the style:
                int specifity = s.Specifity;

                if (specOverride != -1)
                {
                    specifity = specOverride;
                }

                foreach (KeyValuePair <CssProperty, Css.Value> kvp in currentStyle.Properties)
                {
                    // Apply:
                    kvp.Value.SetSpecifity(specifity);
                }

                if (ruleSet == null)
                {
                    return(rule);
                }

                ruleSet[i] = rule;
            }

            return(null);
        }