예제 #1
0
        /// <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;
            }
        }
예제 #2
0
 public static void Hook_Property_Changes(ICssProperty Property)
 {
     Property.onValueChange += (Stage, Prop) =>
     {
         System.Diagnostics.Debugger.Break();
     };
 }
예제 #3
0
        /// <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);
        }
예제 #4
0
        /// <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);
        }
예제 #5
0
        /// <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;
            }
        }
예제 #6
0
        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);
        }
예제 #7
0
        /// <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;
            }
        }
예제 #8
0
        public static CssData AsCss(this ICssProperty prop)
        {
            var cssData = new CssData();

            prop.InsertCss(new CssPropertiesSet(), cssData);
            return(cssData);
        }
예제 #9
0
        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}");
             */
        }
예제 #10
0
        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);
        }
예제 #11
0
 /// <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);
     }
 }
예제 #12
0
        /// <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);
        }
예제 #13
0
        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));
        }
예제 #14
0
 public override bool Equals(ICssProperty element)
 {
     if (element is HighlightCssProperty other)
     {
         return(GetColorCode(other.Element) == GetColorCode(Element));
     }
     return(false);
 }
예제 #15
0
 public override bool Equals(ICssProperty element)
 {
     if (element is ColorCssProperty other)
     {
         return(other.Color == Color);
     }
     return(false);
 }
예제 #16
0
 public override bool Equals(ICssProperty element)
 {
     if (element is JustificationCssProperty other)
     {
         return(other.JustifyContent == JustifyContent);
     }
     return(false);
 }
예제 #17
0
 public override bool Equals(ICssProperty element)
 {
     if (element is UnderlineCssProperty other)
     {
         return(other.Style == Style && other.Color == Color);
     }
     return(false);
 }
예제 #18
0
        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");
        }
예제 #19
0
 /// <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);
 }
예제 #20
0
        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));
        }
예제 #21
0
        /// <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);
     }
 }
예제 #23
0
 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);
 }
예제 #24
0
        internal void Set(ICssProperty Property, ICssProperty Value)
        {
            if (Property is null)
            {
                throw new ArgumentNullException(nameof(Property));
            }

            Contract.EndContractBlock();

            Set(Property.CssName, Value);
        }
예제 #25
0
        /// <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));
        }
예제 #26
0
        /// <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);
            }
        }
예제 #27
0
 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));
     }
 }
예제 #28
0
        /// <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);
            }
        }
예제 #29
0
        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));
        }
예제 #30
0
        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));
            }
        }
예제 #31
0
 public CssRuleViewModel(ICssProperty declaration)
     : this(declaration.Name, declaration.Value)
 {
 }
예제 #32
0
 /// <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);
 }