public override void Select(CssEvent e) { // Get the CS: ComputedStyle cs = e.SelectorTarget.computedStyle; // Create and apply using an informer: SparkInformerNode informer = cs.GetOrCreateVirtualInformer(Priority, true); if (informer.OnStart == null) { // Add a text node as the first child: RenderableTextNode textNode = new RenderableTextNode(); informer.appendChild(textNode); // Setup the delegates! informer.OnStart = delegate(Renderman renderer, SparkInformerNode node){ // Apply first letter - it'll be consumed by the first text node to encounter it: renderer.FirstLetter = node; }; informer.OnEnd = delegate(Renderman renderer, SparkInformerNode node){ // Just in case it wasn't used up: renderer.FirstLetter = null; }; } e.SelectorTarget = informer.RenderData; }
/// <summary>Selects elements from this document using the given CSS selector. /// Do note that this is not designed to be used in high-performance situations and /// you should cache the results as much as possible.</summary> public Dom.NodeList querySelectorAll(string selector, bool one) { // Create results set: Dom.NodeList results = new Dom.NodeList(); if (string.IsNullOrEmpty(selector)) { // Empty set: return(results); } Node root = documentElement; // Create the lexer: Css.CssLexer lexer = new Css.CssLexer(selector, root); List <Css.Selector> all = new List <Css.Selector>(); // Read selectors: lexer.ReadSelectors(all); if (all.Count == 0) { // Invalid selector: return(results); } // Create a blank event to store the targets, if any: CssEvent e = new CssEvent(); // Perform the selection process: (root as IRenderableNode).querySelectorAll(all.ToArray(), results, e, one); return(results); }
/// <summary>Does the given element satisfy this selection requirement?</summary> public override void Select(CssEvent e) { // Change the element being targeted. // Unavailable at the moment; we'll need to check if this is an imported // element in a MathML scope and if so, change the target to the anonymous block. e.CurrentNode = null; }
/// <summary>call this to try to match this selector. /// If it matches, it will return the element which style should be applied to.</summary> public Node Test(ComputedStyle style, CssEvent e) { if (StructureMatch(style, e)) { return(e.CurrentNode); } return(null); }
public override void MoveUpwards(CssEvent e) { // Current node: Node node = e.CurrentNode; if (node != null) { e.CurrentNode = node.previousElementSibling; } }
/// <summary>Gets or creates the virtual.</summary> internal void CreateVirtual(CssEvent e, int priority) { // Get the CS: ComputedStyle cs = e.SelectorTarget.computedStyle; // Create and apply: Node node = cs.GetOrCreateVirtual(priority, "span", true); e.SelectorTarget = (node as IRenderableNode).RenderData; }
public override void MoveUpwards(CssEvent e) { // Current node: Dom.Node node = e.CurrentNode; if (node != null) { e.CurrentNode = node.parentNode; if (e.CurrentNode is Dom.Document) { e.CurrentNode = null; } } }
/// <summary>Doesn't create the virtual if it doesn't exist.</summary> internal void GetVirtual(CssEvent e, int priority) { // Get the CS: ComputedStyle cs = e.SelectorTarget.computedStyle; VirtualElements virts = cs.RenderData.Virtuals; IRenderableNode node = null; if (virts != null) { // Get and apply: node = virts.Get(priority) as IRenderableNode; } // Update the target: e.SelectorTarget = (node == null) ? null : node.RenderData; }
public override void Select(CssEvent e) { // Get/ create the v-child: CreateVirtual(e, Priority); }
/// <summary>True if this selector matches the structure of the DOM where the given CS is.</summary> public bool StructureMatch(ComputedStyle cs, CssEvent e) { // Get the node: Node node = cs.Element; if (node == null) { return(false); } // Apply target - this helps track which element we're actually testing: e.CurrentNode = node; // 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); // Still got a node? if (e.CurrentNode == null) { return(false); } // Try matching again: i++; continue; } return(false); } // 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); // Still got a node? if (e.CurrentNode == null) { return(false); } } } // If we have a pseudo element, make sure parents haven't also matched this selector. if (PseudoElement != null) { // Have any parents matched this selector? Node parent = node.parentNode; while (parent != null) { if (parent["spark-virt"] != null) { // Already on a virtual element - quit there. return(false); } parent = parent.parentNode; } } // All clear! return(true); }
/// <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); }
/// <summary>Gets all child elements with the given tag.</summary> /// <param name="selectors">The selectors to match.</param> /// <returns>The set of all tags with this tag.</returns> public void querySelectorAll(Selector[] selectors, INodeList results, CssEvent e, bool one) { }
public override void Select(CssEvent e) { // Get the v-child (this one does not create it if it doesn't exist): GetVirtual(e, Priority); }
/// <summary>Moves e.CurrentNode through the DOM /// ('backwards', e.g. from something to its parent).</summary> public virtual void MoveUpwards(CssEvent e) { }
public virtual void Select(CssEvent e) { }