CssMedium
Represents a medium rule. More information available at:
http://www.w3.org/TR/css3-mediaqueries/
using AngleSharp.Css;
using AngleSharp.Extensions;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace AngleSharp.Dom.Css
{
internal sealed class CssMedium : CssNode, ICssMedium, ICssNode, IStyleFormattable
{
private static readonly string[] KnownTypes = new string[4] {
Keywords.Screen,
Keywords.Speech,
Keywords.Print,
Keywords.All
};
public IEnumerable<MediaFeature> Features => base.Children.OfType<MediaFeature>();
IEnumerable<IMediaFeature> ICssMedium.Features {
get {
return Features;
}
}
public string Type { get; set; }
public bool IsExclusive { get; set; }
public bool IsInverse { get; set; }
public string Constraints {
get {
IEnumerable<string> values = from m in Features
select m.ToCss();
return string.Join(" and ", values);
}
}
public bool Validate(RenderDevice device)
{
if (!string.IsNullOrEmpty(Type) && KnownTypes.Contains(Type, StringComparison.Ordinal) == IsInverse)
return false;
if (IsInvalid(device))
return false;
return !Features.Any((MediaFeature m) => m.Validate(device) == IsInverse);
}
public override bool Equals(object obj)
{
CssMedium cssMedium = obj as CssMedium;
if (cssMedium != null && cssMedium.IsExclusive == IsExclusive && cssMedium.IsInverse == IsInverse && cssMedium.Type.Is(Type) && cssMedium.Features.Count() == Features.Count()) {
foreach (MediaFeature feature in cssMedium.Features) {
if (!Features.Any(delegate(MediaFeature m) {
if (m.Name.Is(feature.Name))
return m.Value.Is(feature.Value);
return false;
}))
return false;
}
return true;
}
return false;
}
public override int GetHashCode()
{
return base.GetHashCode();
}
public override void ToCss(TextWriter writer, IStyleFormatter formatter)
{
writer.Write(formatter.Medium(IsExclusive, IsInverse, Type, Features));
}
private bool IsInvalid(RenderDevice device)
{
if (!IsInvalid(device, Keywords.Screen, RenderDevice.Kind.Screen) && !IsInvalid(device, Keywords.Speech, RenderDevice.Kind.Speech))
return IsInvalid(device, Keywords.Print, RenderDevice.Kind.Printer);
return true;
}
private bool IsInvalid(RenderDevice device, string keyword, RenderDevice.Kind kind)
{
if (keyword.Is(Type))
return device.DeviceType == kind == IsInverse;
return false;
}
}
}