/// <summary>Gets all child elements with the given tag.</summary> /// <param name="selector">The selector string to match.</param> /// <returns>The set of all tags with this tag.</returns> public HTMLCollection querySelectorAll(string selector, bool one) { // Create results set: HTMLCollection results = new HTMLCollection(); if (string.IsNullOrEmpty(selector)) { // Empty set: return(results); } // Create the lexer: Css.CssLexer lexer = new Css.CssLexer(selector, this); // Read a value: Css.Value value = lexer.ReadValue(); // Read the selectors from the value: List <Selector> selectors = new List <Selector>(); Css.CssLexer.ReadSelectors(null, value, selectors); // Create a blank event to store the targets, if any: CssEvent e = new CssEvent(); // Perform the selection process: querySelectorAll(selectors.ToArray(), results, e, false); return(results); }
/// <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); }
public static Css.Value Load(string text){ CssLexer lexer=new CssLexer(text,null); Css.Value v=lexer.ReadValue(); if(v==null){ v=Empty; } return v; }
/// <summary>Keeps reading selectors and their properties until a > 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(); } }
/// <summary>Reads the properties for this style block from the lexer. /// Essentially treats it like a set of properties only. Terminated by }, null or >.</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; } } }
/// <summary>This e.g. sets AtRuleMode. It's true if this @ rule uses nested selectors. Media and keyframes are two examples.</summary> public virtual void SetupParsing(CssLexer lexer) { }
/// <summary>When a unit declares that it has a start identifier, such as #, this reads the rest of it's value.</summary> public virtual Value ReadStartValue(CssLexer lexer) { return(null); }
/// <summary>Called after a value has been loaded from the stream. Functions etc get it too. /// This is used to, for example, map a value to a faster internal representation.</summary> public virtual void OnValueReady(CssLexer lexer) { }
/// <summary>Attempts to handle the given lexer with this units set.</summary> public Css.Value Handle(CssLexer lexer, bool removeAll) { // By peeking, get as far as we can until a delim of any kind is reached, or we can't go any further. // e.g. 41px*50% - the first will terminate successfully at the x. // Note that we know the current peek matches character. CssUnitHandlers handler = this; int currentIndex = 1; while (true) { // Get the char: char letter = lexer.Peek(currentIndex); currentIndex++; // Got a handler for it? if (handler.Handlers == null) { // Nope! handler.Value, if there is one, is the furthest we can go. break; } int handlerSetCount = handler.Handlers.Count; // Linear scan is faster than a hashtable here. for (int i = 0; i < handlerSetCount; i++) { if (handler.Handlers[i].Character == letter) { // Got it! Keep going. handler = handler.Handlers[i]; goto NextLetter; } } // No letter matches. Stop there. break; NextLetter: continue; } if (handler.Value != null) { // Read off the amount we read now. int start = 2; if (removeAll) { start = 1; } for (int i = start; i < currentIndex; i++) { lexer.Read(); } } return(handler.Value); }
public override void OnValueReady(CssLexer lexer) { string name = this[0].Text.Trim(); Set(name); }