private bool ParseMediaValue(Block token) { switch (token.GrammarSegment) { case GrammarSegment.CurlyBraceOpen: case GrammarSegment.Semicolon: { var container = CurrentRule as ISupportsMedia; if (container != null) { container.Media.AppendMedium(_mediaDefn); } if (CurrentRule is ImportRule) { return ParsePostInstruction(token); } SetParsingContext(ParsingContext.DataBlock); _mediaDefn = null; return token.GrammarSegment == GrammarSegment.CurlyBraceOpen; } case GrammarSegment.Comma: { var container = CurrentRule as ISupportsMedia; if (container != null) { container.Media.AppendMedium(_mediaDefn); } _mediaDefn = null; return true; } case GrammarSegment.Whitespace: { // Do Nothing return true; } default: { if (_mediaDefn == null) _mediaDefn = new MediaDefinition(); switch (token.ToString()) { case "only": _mediaDefn.Modifier = MediaTypeModifier.Only; break; case "not": _mediaDefn.Modifier = MediaTypeModifier.Not; break; case "screen": _mediaDefn.Type = MediaType.Screen; break; case "speech": _mediaDefn.Type = MediaType.Speech; break; case "print": _mediaDefn.Type = MediaType.Print; break; case "all": _mediaDefn.Type = MediaType.All; break; case "braille": _mediaDefn.Type = MediaType.Braille; break; case "embossed": _mediaDefn.Type = MediaType.Embossed; break; case "handheld": _mediaDefn.Type = MediaType.Handheld; break; case "projection": _mediaDefn.Type = MediaType.Projection; break; case "tty": _mediaDefn.Type = MediaType.Tty; break; case "tv": _mediaDefn.Type = MediaType.Tv; break; case "and": // do nothing break; case "(": _mediaProp = new MediaProperty(); break; case ")": if (_mediaProp != null) { var plain = _mediaProp as MediaPropertyPlain; if (plain != null && _terms.Length == 1) { plain.Value = _terms[0]; } else if (!string.IsNullOrEmpty(_compare1) && _terms.Length > 0) { var range = new MediaPropertyRange { Name = _mediaProp.Name }; if (_nameFirst) { if (_compare1.StartsWith("<")) { range.UpperBound = _terms[0]; range.UpperCompare = _compare1; } else { range.LowerBound = _terms[0]; range.LowerCompare = _compare1.Replace('>', '<'); } } else { if (_terms.Length == 1) { if (_compare1.StartsWith(">")) { range.UpperBound = _terms[0]; range.UpperCompare = _compare1.Replace('>', '<'); } else { range.LowerBound = _terms[0]; range.LowerCompare = _compare1; } } else { if (_compare1.StartsWith("<")) { range.LowerBound = _terms[0]; range.LowerCompare = _compare1; range.UpperBound = _terms[1]; range.UpperCompare = _compare2; } else { range.UpperBound = _terms[0]; range.UpperCompare = _compare1.Replace('>', '<'); range.LowerBound = _terms[1]; range.LowerCompare = _compare2.Replace('>', '<'); } } } _mediaProp = range; } _mediaDefn.Properties.Add(_mediaProp); } _compare1 = null; _compare2 = null; _mediaProp = null; _terms = new TermList(); break; case ":": if (_mediaProp != null) _mediaProp = new MediaPropertyPlain { Name = _mediaProp.Name }; break; case "<": case ">": if (string.IsNullOrEmpty(_compare1)) _compare1 = token.ToString(); else _compare2 = token.ToString(); break; case "=": if (string.IsNullOrEmpty(_compare1) || (string.IsNullOrEmpty(_compare2) && _compare1 != "=")) _compare1 = (_compare1 ?? "") + token.ToString(); else _compare2 = (_compare2 ?? "") + token.ToString(); break; default: if (token.GrammarSegment == GrammarSegment.Ident && string.IsNullOrEmpty(_mediaProp.Name)) { _mediaProp.Name = token.ToString(); _nameFirst = string.IsNullOrEmpty(_compare1); } else { ParseSingleValue(token); } break; } return true; } } }
private static bool MediaMatches(MediaDefinition d, GlobalStyleContext settings) { var context = new StyleContext(); var result = (d.Modifier != MediaTypeModifier.Not && (d.Type & settings.Media) > 0) || (d.Modifier == MediaTypeModifier.Not && (d.Type & settings.Media) == 0); if (result) { var width = d.Properties.Where(p => string.Compare(p.Name, "width", StringComparison.OrdinalIgnoreCase) == 0 || p.Name.EndsWith("-width", StringComparison.OrdinalIgnoreCase)); var plainProps = width.OfType<MediaPropertyPlain>(); double px; foreach (var plain in plainProps) { px = ToPx(plain.Value as PrimitiveTerm, context, false); if (plain.Name.StartsWith("max-", StringComparison.OrdinalIgnoreCase) && px > settings.MediaWidth) return false; if (plain.Name.StartsWith("min-", StringComparison.OrdinalIgnoreCase) && px < settings.MediaWidth) return false; } var rangeProps = width.OfType<MediaPropertyRange>(); foreach (var range in rangeProps) { if (range.LowerBound != null) { px = ToPx(range.LowerBound as PrimitiveTerm, context, false); if (settings.MediaWidth < px || (settings.MediaWidth == px && !range.LowerCompare.EndsWith("="))) return false; } if (range.UpperBound != null) { px = ToPx(range.UpperBound as PrimitiveTerm, context, false); if (settings.MediaWidth > px || (settings.MediaWidth == px && !range.UpperCompare.EndsWith("="))) return false; } } } return result; }