Beispiel #1
0
        /// <summary>Removes this selector from all the computed styles it affects, except for the target.
        /// Use ComputedStyle.RemoveMatch(x) instead of calling this directly.</summary>
        internal void Remove()
        {
            for (int i = 0; i < MatchedRoots.Length; i++)
            {
                // Remove it (if it's the target and it was active, it'll also remove the style for us too):
                MatchingRoot root = MatchedRoots[i];

                // Remove from matches:
                ComputedStyle cs = (root.Node as IRenderableNode).ComputedStyle;

                // Remove the node:
                if (root.NextInStyle == null)
                {
                    cs.LastMatch = root.PreviousInStyle;
                }
                else
                {
                    root.NextInStyle.PreviousInStyle = root.PreviousInStyle;
                }

                if (root.PreviousInStyle == null)
                {
                    cs.FirstMatch = root.NextInStyle;
                }
                else
                {
                    root.PreviousInStyle.NextInStyle = root.NextInStyle;
                }

                if (root.IsTarget && Active)
                {
                    // Remove props:
                    cs.MatchChanged(Style, false);
                }
            }
        }
Beispiel #2
0
        /// <summary>Applies a structurally matched selector to the DOM.
        /// Occurs shortly after StructureMatch.</summary>
        public MatchingSelector BakeToTarget(ComputedStyle cs, CssEvent e)
        {
            // Get the node:
            Node node = cs.Element;

            // First, generate our instance:
            MatchingSelector ms = new MatchingSelector();

            // Update it:
            ms.Selector     = this;
            ms.MatchedRoots = new MatchingRoot[RootCount];

            // For each root, create a MatchingRoot object.

            // Apply target - this helps track which element we're actually testing:
            e.CurrentNode    = node;
            e.SelectorTarget = null;

            // We always start from the tail and work backwards.
            // If we get a match, then the caller can do whatever it wants to the target.

            for (int i = RootCount - 1; i >= 0; i--)
            {
                // Get the matcher:
                RootMatcher rm = Roots[i];

                // Try matching this root:
                if (!rm.TryMatch(e.CurrentNode))
                {
                    // Failed! If we had a matcher and it has Repeat set true, try again:
                    if (rm.NextMatcher != null && rm.NextMatcher.Repeat)
                    {
                        // Move target:
                        rm.NextMatcher.MoveUpwards(e);

                        // Try matching again:
                        i++;
                        continue;
                    }
                }
                else
                {
                    // Match! e.CurrentNode is the node to add.

                    // Create the instance:
                    MatchingRoot matchedRoot = new MatchingRoot();
                    matchedRoot.Root     = rm;
                    matchedRoot.Selector = ms;
                    matchedRoot.Node     = e.CurrentNode;

                    // Get renderable node:
                    IRenderableNode renderable = (e.CurrentNode as IRenderableNode);

                    // Add to selector:
                    ms.MatchedRoots[i] = matchedRoot;

                    // Add:
                    ComputedStyle nodeCs = renderable.ComputedStyle;

                    // Push the match now into the linked list:
                    if (nodeCs.FirstMatch == null)
                    {
                        nodeCs.FirstMatch = matchedRoot;
                        nodeCs.LastMatch  = matchedRoot;
                    }
                    else
                    {
                        matchedRoot.PreviousInStyle  = nodeCs.LastMatch;
                        nodeCs.LastMatch.NextInStyle = matchedRoot;
                        nodeCs.LastMatch             = matchedRoot;
                    }

                    if (rm.IsTarget)
                    {
                        // Update the target now:
                        e.SelectorTarget = renderable.RenderData;
                    }
                }

                // If we have a structure matcher, run it now. It'll move CurrentNode for us:
                if (rm.PreviousMatcher != null)
                {
                    // Move target:
                    rm.PreviousMatcher.MoveUpwards(e);
                }
            }

            // Final pass - if we have a pseudo-element, apply it now:
            if (PseudoElement != null)
            {
                PseudoElement.Select(e);
            }

            // Apply target:
            ms.Target = e.SelectorTarget;

            // Finally, refresh all:
            ms.ResetActive();

            return(ms);
        }