/// <summary> /// Throws an exception if the value is invalid according to the currently set options /// </summary> /// <param name="Value"></param> /// <returns></returns> public void CheckAndThrow(ICssProperty Owner, CssValue Value) { if (Owner is null) { throw new ArgumentNullException(nameof(Owner)); } if (Value is null) { throw new ArgumentNullException(nameof(Value)); } Contract.EndContractBlock(); if (!Is_Valid_Value_Type(Value.Type)) { throw new CssException($"The property({Enum.GetName(typeof(EMediaFeatureName), Name.Value)}) cannot be set to an {Enum.GetName(typeof(ECssValueTypes), Value.Type)}!"); } switch (Value.Type) { case ECssValueTypes.KEYWORD: { // check this value against our keyword whitelist if (KeywordWhitelist is object && KeywordWhitelist.Count > 0) { //if (!Array.Exists(keywordWhitelist, x => x.Equals(Value.AsString(), StringComparison.InvariantCultureIgnoreCase))) if (!KeywordWhitelist.Contains(Value.AsString())) { throw new CssException($"Property({Enum.GetName(typeof(EMediaFeatureName), Name.Value)}) does not accept '{Value.AsString()}' as a value!"); } } } break; } }
public static void Hook_Property_Changes(ICssProperty Property) { Property.onValueChange += (Stage, Prop) => { System.Diagnostics.Debugger.Break(); }; }
/// <summary> /// /// </summary> /// <param name="Property"></param> /// <returns></returns> private void CascadeProperty(ICssProperty Property) { // Extract this property from every CssPropertySet that has a value for it //var propertyList = CssRules.Values.Select(propSet => { return propSet[Property.CssName]; }).ToList(); var propertyList = new List <ICssProperty>(4); foreach (var propSet in CssRules.Values) { propertyList.Add(propSet[Property.CssName]); } // Order these properties according to CSS 3.0 specifications propertyList.Sort(CssPropertyComparator.Instance); // Cascade this list and get what CSS calls the 'Specified' value ICssProperty Value = Property; foreach (ICssProperty o in propertyList) { /*var cascade = Value.CascadeAsync(o); * Task.WhenAll(cascade).Wait();// we HAVE to wait here * if (cascade.Result) break;// stop cascading the instant we find a set value*/ var changed = Value.Cascade(o); if (changed) { break; // stop cascading the instant we find a set value } } string SourceState = Value.Source.ToString(); Cascaded.Set(Property.CssName, Value); }
/// <summary> /// The value of pre-cascade property has changed /// </summary> /// <param name="Stage"></param> /// <param name="Property"></param> private void Property_onChanged(EPropertyStage Stage, ICssProperty Property) { SetProperties.SetFlag(Property.CssName.Value, Property.HasValue); /*if (!Property.HasValue) SetProperties.Remove(Property.CssName); * else SetProperties.Add(Property.CssName);*/ if (Property.CssName is null) { throw new Exception($"Cannot fire onChange events for unnamed property! (Name: {Property.CssName}"); } StyleDefinition def = CssDefinitions.StyleDefinitions[Property.CssName]; if (def is null) { throw new Exception($"Cannot find a definition for Css property: \"{Property.CssName}\""); } EPropertyDirtFlags Flags = def.Flags; StackTrace Stack = null; #if DEBUG //stack = new StackTrace(STACK_FRAME_OFFSET, true); #endif Property_Changed?.Invoke(Stage, Property, Flags, Stack); }
/// <summary> /// Throws an exception if the value is invalid according to the currently set options /// </summary> /// <param name="Value"></param> /// <returns></returns> public void CheckAndThrow(ICssProperty Owner, CssValue Value) { if (Owner is null) { throw new ArgumentNullException(nameof(Owner)); } if (Value is null) { throw new ArgumentNullException(nameof(Value)); } Contract.EndContractBlock(); if (!Is_Valid_Value_Type(Value.Type)) { throw new CssException($"The property({Name}) cannot be set to an {Enum.GetName(typeof(ECssValueTypes), Value.Type)}!"); } switch (Value.Type) { case ECssValueTypes.KEYWORD: { // check this value against our keyword whitelist if (KeywordWhitelist != null && KeywordWhitelist.Count > 0) { if (!KeywordWhitelist.Contains(Value.AsString())) { throw new CssException($"Property({Name}) does not accept '{Value.AsString()}' as a value!"); } } } break; } }
public static CssValue Color_Used(ICssProperty Property) { if (Property == null) { throw new ArgumentNullException(nameof(Property)); } Contract.EndContractBlock(); var prop = (Property as CssProperty); CssValue Value = prop.Computed; if (Value.Type == ECssValueTypes.KEYWORD) { var keyword = Value.AsEnum <EColor>(); switch (keyword) { case EColor.CurrentColor: { /* The used value of the ‘currentColor’ keyword is the computed value of the ‘color’ property. */ return(Property.Owner.Style.Cascaded.Color.Computed); } } } return(Value); }
/// <summary> /// Throws an exception if the value is invalid according to the currently set options /// </summary> /// <param name="Value"></param> /// <returns></returns> public void CheckAndThrow(ICssProperty Owner, CssValue Value) { switch (Value.Type) { case ECssValueTypes.AUTO: if (!AllowAuto) { throw new Exception(string.Concat("The property(", Owner.CssName, ") cannot be set to AUTO!")); } break; case ECssValueTypes.INHERIT: if (!AllowInherited) { throw new Exception(string.Concat("The property(", Owner.CssName, ") cannot be set to INHERITED!")); } break; case ECssValueTypes.PERCENT: if (!AllowPercentage) { throw new Exception(string.Concat("The property(", Owner.CssName, ") cannot be set to Percentages!")); } break; default: break; } }
public static CssData AsCss(this ICssProperty prop) { var cssData = new CssData(); prop.InsertCss(new CssPropertiesSet(), cssData); return(cssData); }
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}"); */ }
public static CssValue Color_Specified(ICssProperty Property) { if (Property == null) { throw new ArgumentNullException(nameof(Property)); } Contract.EndContractBlock(); var prop = (Property as CssProperty); if (prop.Specified.Type != ECssValueTypes.KEYWORD) { return(prop.Specified); } CssValue Value = prop.Specified; var keyword = Value.AsEnum <EColor>(); switch (keyword) { case EColor.CurrentColor: { /* If the ‘currentColor’ keyword is set on the ‘color’ property itself, it is treated as ‘color: inherit’. */ if (Property.CssName == ECssPropertyID.Color) { return(Property.Find_Inherited_Value()); } } break; } return(Value); }
/// <summary> /// Throws an exception if any of the given values are invalid according to the currently set options /// </summary> /// <param name="Value"></param> /// <returns></returns> public void CheckAndThrow(ICssProperty Owner, CssValueList Values) { foreach (CssValue Value in Values) { CheckAndThrow(Owner, Value); } }
/// <summary> /// A post-cascade property has changed assigned values /// </summary> /// <param name="Property"></param> /// <param name="Flags"></param> /// <param name="Stack"></param> private void Handle_Cascaded_Property_Change(EPropertyStage Stage, ICssProperty Property, EPropertyDirtFlags Flags, StackTrace Stack) { bool IsFlow = (Flags & EPropertyDirtFlags.Flow) != 0;// Layout bool IsBlock = (Flags & EPropertyDirtFlags.Box) != 0; bool IsVisual = (Flags & EPropertyDirtFlags.Visual) != 0; bool IsFont = (Flags & EPropertyDirtFlags.Text) != 0; // If the value that changed was a specified one and it affects the block then we need to update our block if (IsBlock && Stage >= EPropertyStage.Specified) { // Flag us dirty so we can resolve next time its called SetFlag(EPropertySystemDirtFlags.NeedsToResolveBlock); // Notify our parent by flagging them aswell // Owner.Box.Flag(EBoxInvalidationReason.Property_Changed); // Owner.Box.FlagProperty(Flags); } // Update our dirt flags appropriately if (IsFlow || IsVisual) { SetFlag(EPropertySystemDirtFlags.NeedsToResolveBlock); } if (IsFont) { SetFlag(EPropertySystemDirtFlags.NeedsToResolveFont); } //Logging.Log.Info("[Property Changed]: {0}", Prop.FieldName); onProperty_Change?.Invoke(Property, Flags, Stack); }
public static CssValue Font_Size_Used(ICssProperty Property) {/* Docs: https://www.w3.org/TR/css-fonts-3/#font-size-prop */ if (Property == null) { throw new ArgumentNullException(nameof(Property)); } Contract.EndContractBlock(); double?v = (Property as CssProperty).Computed.Resolve(); if (!v.HasValue) { throw new CssException($"Unable to resolve absolute length for Used \"{Property.CssName}\" value."); } Contract.EndContractBlock(); double Size = v.Value; if (Size < 9.0)// The specifications say we shouldnt render a font less than 9px in size { Size = 9.0; } // Round the size up to the nearest whole pixel value Size = Math.Round(Size, MidpointRounding.AwayFromZero); return(CssValue.From(Size)); }
public override bool Equals(ICssProperty element) { if (element is HighlightCssProperty other) { return(GetColorCode(other.Element) == GetColorCode(Element)); } return(false); }
public override bool Equals(ICssProperty element) { if (element is ColorCssProperty other) { return(other.Color == Color); } return(false); }
public override bool Equals(ICssProperty element) { if (element is JustificationCssProperty other) { return(other.JustifyContent == JustifyContent); } return(false); }
public override bool Equals(ICssProperty element) { if (element is UnderlineCssProperty other) { return(other.Style == Style && other.Color == Color); } return(false); }
private void Handle_Cascaded_Transform_Change(EPropertyStage Stage, ICssProperty Property) { if (Stage < EPropertyStage.Actual)// wait for the Actual value stage { return; } throw new NotImplementedException("Transforms are not yet implemented"); }
/// <summary> /// A state-specific property changed, we need to resolve this single property /// </summary> private void Handle_Declared_Property_Change(EPropertyStage Stage, ICssProperty Property, EPropertyDirtFlags Flags, StackTrace Origin) { /* XXX: * To be honest cascading here doesnt make sense * if a declared property changes that wont always change the value of our cascaded property. * We should check if this property IS the cascaded property and if so then just update that single property! */ CascadeProperty(Property); }
internal CssValue Derive_UsedValue(ICssProperty Property) {/* Docs: https://www.w3.org/TR/css-cascade-3/#used */ var ResolutionDelegate = Property.Definition.PropertyStageResolver[(int)EPropertyStage.Used]; if (ResolutionDelegate is object) { return((CssValue)ResolutionDelegate.Invoke(Property)); } return(new CssValue(this)); }
/// <summary> /// An inheritable property of an element within our hierarchy has changed. /// </summary> /// <param name="Sender">The element whose property changed</param> /// <param name="Property"></param> public async Task Handle_Inherited_Property_Change_In_Hierarchy(Element Sender, ICssProperty Property) { // check if we have this property set to inherit ICssProperty prop = Cascaded.Get(Property); if (prop.IsInherited) { // we dont have to recascade this value, we just need to update its interpreted values prop.Update(); } }
private void SetProperty(ICssProperty property) { if (property.IsShorthand) { SetShorthand(property); } else { SetLonghand(property); } }
private bool BuildSingleRun(OpenXmlElement elem, out ICssProperty property) { if (_runMappings.TryGetValue(elem.GetType(), out Func <ICssProperty> factory)) { property = factory(); property.OpenXmlElement = elem; return(true); } property = null; return(false); }
internal void Set(ICssProperty Property, ICssProperty Value) { if (Property is null) { throw new ArgumentNullException(nameof(Property)); } Contract.EndContractBlock(); Set(Property.CssName, Value); }
/// <summary> /// Finds the property within this style set that matches the given property /// </summary> /// <param name="Property"></param> /// <returns></returns> internal ICssProperty Get(ICssProperty Property) { if (Property is null) { throw new ArgumentNullException(nameof(Property)); } Contract.EndContractBlock(); return(Get(Property.CssName)); }
/// <summary> /// Removes a style from the document. /// </summary> /// <param name="tag">Tag the style belongs to</param> /// <param name="styles">Style rule that contains the style to be removed</param> /// <param name="style">Style to be removed</param> /// <param name="reason">Reason for removal</param> private void RemoveStyle(IElement tag, ICssStyleDeclaration styles, ICssProperty style, RemoveReason reason) { var e = new RemovingStyleEventArgs { Tag = tag, Style = style, Reason = reason }; OnRemovingStyle(e); if (!e.Cancel) { styles.RemoveProperty(style.Name); } }
public static CssValue Containing_Block_Logical_Height(ICssProperty Property, double Percent) { if (!Property.Owner.Box.Containing_Box_Explicit_Height) { return(CssValue.Zero); } else { var resolved = Percent * CssCommon.Get_Logical_Height(Property.Owner.Style.WritingMode, Property.Owner.Box.Containing_Box); return(CssValue.From(resolved, ECssUnit.PX)); } }
/// <summary> /// Throws an exception if any of the given values are invalid according to the currently set options /// </summary> /// <param name="Value"></param> /// <returns></returns> public void CheckAndThrow(ICssProperty Owner, CssValueList Values) { if (Values is null) { throw new ArgumentNullException(nameof(Values)); } Contract.EndContractBlock(); foreach (CssValue Value in Values) { CheckAndThrow(Owner, Value); } }
internal CssValue Derive_ActualValue(ICssProperty Property) {/* Docs: https://www.w3.org/TR/css-cascade-3/#actual */ // the Actual value does not get 'resolved' it gets restricted. var ResolutionDelegate = Property.Definition.PropertyStageResolver[(int)EPropertyStage.Actual]; if (ResolutionDelegate is object) { return((CssValue)ResolutionDelegate(Property)); } return(new CssValue(this)); }
public void AddMany_Test() { var props = new ICssProperty[] { new MockProp1(), new MockProp2() }; _instance.AddMany(props); foreach (var prop in props) { Assert.IsTrue(_instance.Contains(prop)); } }
public CssRuleViewModel(ICssProperty declaration) : this(declaration.Name, declaration.Value) { }
/// <summary> /// Remove a style from the document. /// </summary> /// <param name="tag">tag where the style belongs</param> /// <param name="styles">collection where the style to belongs</param> /// <param name="style">to be removed</param> /// <param name="reason">reason why to be removed</param> private void RemoveStyle(IElement tag, ICssStyleDeclaration styles, ICssProperty style, RemoveReason reason) { var e = new RemovingStyleEventArgs { Tag = tag, Style = style, Reason = reason }; OnRemovingStyle(e); if (!e.Cancel) styles.RemoveProperty(style.Name); }