public static AttributeValue Parse(AtomicName <EAttributeName> Name, string Input) { var Def = AttributeDefinition.Lookup(Name); Def.Parse(Input, out dynamic outVal); return(new AttributeValue(Def.Type, Input, outVal)); }
internal ICssProperty Get(AtomicName <ECssPropertyID> CssName) { if (CssName is null) { throw new ArgumentNullException(nameof(CssName)); } if (CssName.Value < 0) { throw new ArgumentOutOfRangeException($"Invalid CSS property ID (negative value): {CssName}"); } Contract.EndContractBlock(); if (CssName.Value >= CssProperties.Count) { return(null); } return(CssProperties[CssName.Value]); /* * if (CssPropertyMap.TryGetValue(CssName, out ICssProperty prop)) * return prop; * * throw new KeyNotFoundException($"Unable find style property: {CssName}"); */ }
internal void Set(AtomicName <ECssPropertyID> CssName, ICssProperty Value) { if (CssName is null) { throw new ArgumentNullException(nameof(CssName)); } if (CssName.Value < 0) { throw new ArgumentOutOfRangeException($"Invalid CSS property ID (negative value): {CssName}"); } Contract.EndContractBlock(); if (CssName.Value >= CssProperties.Count) {// Make more room int diff = CssName.Value - CssProperties.Count; for (int i = 0; i < diff; i++) { CssProperties.Add(null); } } CssProperties[CssName.Value] = Value; return; /* * if (CssPropertyMap.TryGetValue(CssName, out ICssProperty Property)) * { * Property.Overwrite(Value); * return; * } * * throw new KeyNotFoundException($"Unable find style property: {CssName}"); */ }
/// <summary> /// Creates a new CSS property definition /// </summary> /// <param name="Name">CSS property name</param> /// <param name="Inherited">Do child elements inherit this value if they are unset?</param> /// <param name="Flags">Indicates what aspects of an element this property affects</param> /// <param name="Initial">Default value for the property</param> /// <param name="Keywords">List of keywords which can be assigned to this property</param> /// <param name="IsPrivate">If TRUE then this property cannot be set from style-sheets</param> public StyleDefinition(AtomicName <ECssPropertyID> Name, bool Inherited, EPropertyDirtFlags Flags, CssValue Initial, ECssValueTypes AllowedTypes = 0x0, string[] Keywords = null, bool IsPrivate = false, CssPercentageResolver Percentage_Resolver = null, params Tuple <EPropertyStage, PropertyResolverFunc>[] Resolvers) { this.Name = Name; this.Flags = Flags; this.IsPrivate = IsPrivate; this.Inherited = Inherited; this.Initial = Initial; this.Percentage_Resolver = Percentage_Resolver; if (Keywords is null) { keywordWhitelist = Array.Empty <string>(); } else { keywordWhitelist = Keywords.ToArray(); } // Append the specified allowed types to our defaults this.AllowedTypes |= AllowedTypes; // Setup our resolver index foreach (var o in Resolvers) { propertyStageResolver[(int)o.Item1] = o.Item2; } }
public UrlOrigin(AtomicName <EUrlScheme> scheme, UrlHost host, ushort?port, string domain) { Type = EOriginType.Tuple; Scheme = scheme; Host = host; Port = port; Domain = domain; }
private static Name ToAtomicName(char c, IPosition position) { var an = new AtomicName(c, position, dummyNotion); return an; //var result = new ElementaryForm<NameInstance>(an); // //an.Notation = result; //return result; }
public AttributeSelector(NamespacePrefixToken Namespace, string Attrib, CssToken OperatorToken, string Value) : base(ESimpleSelectorType.AttributeSelector) { this.Namespace = Namespace; this.AttributeName = Attrib; if (Value == null) { Value = string.Empty; } this.Value = Value; if (OperatorToken == null || OperatorToken.Type == ECssTokenType.Delim && (OperatorToken as DelimToken).Value == '>') { this.Operator = ECssAttributeOperator.Isset; } else { switch (OperatorToken.Type) { case ECssTokenType.Delim: { if ((OperatorToken as DelimToken).Value == '=') { this.Operator = ECssAttributeOperator.Equals; } } break; case ECssTokenType.Dash_Match: this.Operator = ECssAttributeOperator.PrefixedWith; break; case ECssTokenType.Include_Match: this.Operator = ECssAttributeOperator.Includes; break; case ECssTokenType.Prefix_Match: this.Operator = ECssAttributeOperator.StartsWith; break; case ECssTokenType.Suffix_Match: this.Operator = ECssAttributeOperator.EndsWith; break; case ECssTokenType.Substring_Match: this.Operator = ECssAttributeOperator.Contains; break; default: throw new CssSelectorException("Attribute selector: operator token-to-enum translation not implemented for (", OperatorToken, ")!"); } } }
public static AttributeDefinition Lookup(AtomicName <EAttributeName> Name) { if (DomDefinitions.AttributeDefinitions.TryGetValue(Name, out List <AttributeDefinition> definitionList)) { if (definitionList.Count > 1) { throw new Exception($"The content attribute \"{Name}\" has multiple definitions, an element type must be specified to determine the correct definition"); } return(definitionList[0]); } return(null); }
/// <summary> /// Creates a DOM attribute definition /// </summary> /// <param name="Name">DOM attribute name</param> /// <param name="Flags">Indicates what aspects of an element this property affects</param> /// <param name="MissingValueDefault">Default value for the attribute</param> /// <param name="Keywords">List of keywords which can be assigned to this attribute</param> public AttributeDefinition(AtomicName <EAttributeName> Name, EAttributeType Type = 0x0, AttributeValue MissingValueDefault = null, AttributeValue InvalidValueDefault = null, EAttributeFlags Flags = 0x0, string[] Keywords = null, Type enumType = null, dynamic lowerRange = null, dynamic upperRange = null, string[] SupportedTokens = null) : this(Keywords, SupportedTokens) { this.ElementType = typeof(Element); this.Name = Name; this.Flags = Flags; this.MissingValueDefault = MissingValueDefault; this.InvalidValueDefault = InvalidValueDefault; this.enumType = enumType; this.LowerRange = lowerRange; this.UpperRange = upperRange; // Append the specified allowed types to our defaults this.Type |= Type; }
/// <summary> /// Define a new Css Styling property /// </summary> /// <param name="Name">CSS property name</param> /// <param name="Inherited">Do child elements inherit this value if they are unset?</param> /// <param name="Flags">Indicates what aspects of an element this property affects</param> /// <param name="Initial">Default value for the property</param> /// <param name="DisallowedTypes">Bitmask of all value data types which cannot be assigned to this property</param> /// <param name="Keywords">List of keywords which can be assigned to this property</param> /// <param name="IsPrivate">If TRUE then this property cannot be set from style-sheets</param> public MediaDefinition(AtomicName <EMediaFeatureName> Name, EMediaFeatureType Type, ECssValueTypes AllowedTypes, string[] Keywords = null) { this.Name = Name; this.Type = Type; if (Keywords is null) { keywordWhitelist = Array.Empty <string>(); } else { keywordWhitelist = Keywords; } // Append the specified allowed types to our defaults this.AllowedTypes |= AllowedTypes; }
public static void Enqueue_Reaction(Element element, AtomicName <EReactionName> Reaction, params object[] Args) {/* Docs: https://html.spec.whatwg.org/multipage/custom-elements.html#enqueue-a-custom-element-callback-reaction */ #if ENABLE_HTML if (!element.isCustom) { return; } /* 1) Let definition be element's custom element definition. */ CustomElementDefinition def = element.ownerDocument.defaultView.customElements.Lookup(element.ownerDocument, element.NamespaceURI, element.tagName, element.is_value); if (def == null) { return; } /* 2) Let callback be the value of the entry in definition's lifecycle callbacks with key callbackName. */ var callback = def.lifecycleCallbacks[Reaction]; /* 3) If callback is null, then return */ if (callback == null) { return; } /* 4) If callbackName is "attributeChangedCallback", then: */ if (Reaction == EReactionName.AttributeChanged) { /* 1) Let attributeName be the first element of args. */ AtomicName <EAttributeName> attributeName = Args[0] as AtomicName <EAttributeName>; /* 2) If definition's observed attributes does not contain attributeName, then return. */ if (!def.observedAttributes.Contains(attributeName)) { return; } } /* 5) Add a new callback reaction to element's custom element reaction queue, with callback function callback and arguments args. */ element.Custom_Element_Reaction_Queue.Enqueue(new ReactionCallback(callback, Args)); /* 6) Enqueue an element on the appropriate element queue given element. */ element.ownerDocument.defaultView.Reactions.Enqueue_Element(element); #endif }
public AttributeTokenList(Element ownerElement, AtomicName <EAttributeName> localName, T[] supportedTokens) { SupportedTokens = new HashSet <T>(supportedTokens); /* 1) Let element be associated element. */ this.ownerElement = ownerElement; /* 2) Let localName be associated attribute’s local name. */ this.localName = localName; if (ownerElement.tokenListMap.ContainsKey(localName)) { throw new DOMException($"Cannot link {nameof(DOMTokenList)} to element because it already has one defined for attribute \"{localName}\""); } else { ownerElement.tokenListMap.Add(localName, this); } /* 3) Let value be the result of getting an attribute value given element and localName. */ this.ownerElement.find_attribute(localName, out Attr attr); //var value = attr?.Value.Get_String(); /* 4) Run the attribute change steps for element, localName, value, value, and null. */ run_attribute_change_steps(ownerElement, localName, attr.Value, attr.Value, null); }
public static AttributeDefinition Lookup(AtomicName <EAttributeName> Name, Type elementType) { if (elementType == null) { throw new ArgumentNullException(nameof(elementType)); } if (DomDefinitions.AttributeDefinitions.TryGetValue(Name, out List <AttributeDefinition> definitionList)) { foreach (var def in definitionList) { if (elementType.IsAssignableFrom(def.ElementType)) { return(def); } } throw new Exception($"Unable to find the content attribute(\"{Name}\") definition for the element type \"{elementType.Name}\""); } return(null); }
public AttributeTokenList(Element ownerElement, AtomicName <EAttributeName> localName) : this(ownerElement, localName, null) { }
/// <summary> /// Resolves all Css properties to their specified values by cascading /// </summary> public void Cascade() { /* XXX: LOTS of room for speed improvement here. We should avoid using LINQ statements in performance critical areas like this. */ var benchmark_id = Benchmark.Start("style-cascade"); // Get a list of only the properties with an Assigned value AsyncCountdownEvent ctdn = null; /* * HashSet<AtomicName<ECssPropertyID>> targetFields = new HashSet<AtomicName<ECssPropertyID>>(); * List<HashSet<AtomicName<ECssPropertyID>>> allFields = CssRules.Values.Select(x => { return x.SetProperties; }).ToList(); */ var targetFields = new FlagCollection <ECssPropertyID>((int)ECssPropertyID.MAX_VALUE); List <FlagCollection <ECssPropertyID> > allFields = CssRules.Values.Select(x => { return(x.SetProperties); }).ToList(); // Remove duplicates //foreach (HashSet<AtomicName<ECssPropertyID>> fields in allFields) foreach (FlagCollection <ECssPropertyID> fields in allFields) { targetFields.And(fields); } if (targetFields.ActiveFlags > 0) { // Cascade all those set values ctdn = new AsyncCountdownEvent(targetFields.ActiveFlags); // Loop over all target properties foreach (int flagIndex in targetFields) //Parallel.ForEach(targetFields, async (AtomicString propName) => { try { AtomicName <ECssPropertyID> propName = new AtomicName <ECssPropertyID>(flagIndex); // Extract this property from every CssPropertySet that has a value for it var propertyList = CssRules.Values.Select(x => { return(x.Get(propName)); }).ToList(); // Order these properties according to CSS 3.0 specifications propertyList.Sort(CssPropertyComparator.Instance); /* * // Because cascading overwrites an existing value with the one from the next propertyset we need to reverse this list. * propertyList.Reverse();*/ // Cascade this list and get what CSS calls the 'Specified' value ICssProperty Value = Cascaded.Get(propName); foreach (ICssProperty o in propertyList) { //bool b = await Value.CascadeAsync(o); bool b = Value.Cascade(o); if (b) { break; // stop cascading the instant we find a set value } } string SourceState = Value.Source.ToString(); //await Cascaded.Set(propName, Value); Cascaded.Set(propName, Value); } finally { ctdn.Signal(); } //}); } ctdn.WaitAsync().Wait(); } // Recalculate ALL properties var PropList = Cascaded.GetAll().ToList(); /*ctdn = new AsyncCountdownEvent(PropList.Count); * Parallel.For(0, PropList.Count, (int i) => * { * ICssProperty prop = PropList[i]; * // We always want to compute these now to get their values resolved. otherwise any with just assigned values will not interpret and output computed values. * prop.Update(ComputeNow: true); * ctdn.Signal(); * }); * ctdn.WaitAsync().Wait();*/ for (int i = 0; i < PropList.Count; i++) { ICssProperty prop = PropList[i]; // We always want to compute these now to get their values resolved. otherwise any with just assigned values will not interpret and output computed values. prop.Update(ComputeNow: true); } // Any values that changed due to this cascade should have thrown a property change event to let the style system know what it needs to update // Remove cascade flag ClearFlag(EPropertySystemDirtFlags.NeedsToCascade); Benchmark.Stop(benchmark_id); }
/// <summary> /// Creates a new attribute filter that matches a BOOLEAN attribute /// </summary> /// <param name="Name">Athe attribute to check</param> public FilterAttribute(AtomicName <EAttributeName> Name, AttributeValue Value) { this.Name = Name; this.Value = Value; }
public DOMEnumList(Element ownerElement, AtomicName <EAttributeName> localName, EnumType[] supportedTokens) : base(ownerElement, localName, supportedTokens) { }
public DOMTokenList(Element ownerElement, AtomicName <EAttributeName> localName, string[] supportedTokens) : base(ownerElement, localName, null) { }
/// <summary> /// Creates a new attribute filter that matches a BOOLEAN attribute /// </summary> /// <param name="Name">Athe attribute to check</param> public FilterAttribute(AtomicName <EAttributeName> Name) { this.Name = Name; IsBoolean = true; }
/// <summary> Creates a test notion, namely a binary operator |: bool×bool→bool. </summary> /// <param name="orName"> Will contain the name for the or operator. </param> private static Notion CreateOrNotion(out Name orName) { char orOpChar = '|'; var x = DefaultNotions.Subset; Notion orNotion = new Notion(Signature.From(Booleans, Booleans, Booleans), orOpChar.ToString(), true); LinearNotions.Add(orNotion, DomainKind.Binary, Associativity.Left, 0);//TODO: do this via workspace rather than static method Contract.Assert(orNotion.Domain is LinearSet); orName = new AtomicName(new AtomicNameInstance(orOpChar, new LinearPosition(0)), orNotion).Finalize(); return orNotion; }
public NullableLengthProperty(AtomicName <ECssPropertyID> CssName, ICssElement Owner, WeakReference <CssComputedStyle> Source, bool Locked) : base(CssName, Owner, Source, Locked) { }
public CSSPseudoElement(AtomicName <EPseudoElement> type, Element element) { this.type = type; this.element = element; }
{/* Docs: https://dom.spec.whatwg.org/#interface-domtokenlist */ #region Constructor public DOMTokenList(Element ownerElement, AtomicName <EAttributeName> localName) : base(ownerElement, localName) { }
public ICssProperty this[AtomicName <ECssPropertyID> CssName] => Get(CssName);
public MultiStringProperty(AtomicName <ECssPropertyID> CssName, ICssElement Owner, WeakReference <CssComputedStyle> Source, bool Locked) : base(CssName, Locked, Source, Owner) { }
/// <summary> /// </summary> /// <param name="Attrib">The attribute name for this selector</param> /// <param name="Operator">String token that defines the method of comparison</param> /// <param name="Value"></param> public AttributeSelector(NamespacePrefixToken Namespace, string Attrib) : base(ESimpleSelectorType.AttributeSelector) { this.Namespace = Namespace; this.AttributeName = Attrib; this.Operator = ECssAttributeOperator.Isset; }