コード例 #1
0
 public void WriteSelectorBlock(SelectorAndBlock block)
 {
     WriteSelector(block.Selector);
     StartClass();
     foreach (var rule in block.Properties.Cast <NameValueProperty>())
     {
         WriteRule(rule);
     }
     EndClass();
 }
コード例 #2
0
ファイル: CacheBreak.cs プロジェクト: modulexcite/More
        private static SelectorAndBlock CacheBreakBlock(SelectorAndBlock block)
        {
            var ret = new List <Property>();

            foreach (var prop in block.Properties.Cast <NameValueProperty>())
            {
                ret.Add(CacheBreakProperty(prop));
            }

            return(new SelectorAndBlock(block.Selector, ret, block.ResetContext, block.Start, block.Stop, block.FilePath));
        }
コード例 #3
0
ファイル: UnrollVerify.cs プロジェクト: modulexcite/More
        private static void Verify(SelectorAndBlock block)
        {
            var nestedBlock = block.Properties.OfType <NestedBlockProperty>().ToList();
            var innerMedia  = block.Properties.OfType <InnerMediaProperty>().ToList();

            if (nestedBlock.Count != 0)
            {
                throw new InvalidOperationException("It shouldn't be possible for nested blocks to remain here");
            }

            foreach (var media in innerMedia)
            {
                Current.RecordError(ErrorType.Compiler, media, "@media blocks cannot be nested within each other");
            }
        }
コード例 #4
0
ファイル: AutoPrefix.cs プロジェクト: modulexcite/More
        private static SelectorAndBlock PrefixBlock(SelectorAndBlock block)
        {
            var ret = new List <Property>();

            var asNameValue = block.Properties.Cast <NameValueProperty>().ToList();

            foreach (var prop in asNameValue)
            {
                var possible = PrefixProperty(prop);

                // No prefix versions, no point in any conflict checking; just put it back and continue
                if (possible == null)
                {
                    ret.Add(prop);
                    continue;
                }

                var alreadyPresent =
                    asNameValue.Where(
                        w =>
                        possible.Any(p =>
                                     p.Name.Equals(w.Name, StringComparison.InvariantCultureIgnoreCase) &&
                                     p.Name != prop.Name
                                     )
                        ).ToList();

                foreach (var dupe in alreadyPresent)
                {
                    var dupeOf = possible.Where(w => w.Name == dupe.Name).ToList();

                    if (dupeOf.All(d => d.Value.Equals(dupe.Value)))
                    {
                        Current.RecordInfo("Prefixed property " + dupe.Name + " in '" + block.Selector + "' could have been generated automatically");
                    }
                }

                possible.RemoveAll(x => alreadyPresent.Any(y => y.Name.Equals(x.Name, StringComparison.InvariantCultureIgnoreCase)));

                ret.AddRange(possible);
            }

            return(new SelectorAndBlock(block.Selector, ret, block.ResetContext, block.Start, block.Stop, block.FilePath));
        }
コード例 #5
0
        public void WriteSelectorBlock(SelectorAndBlock block)
        {
            WriteSelector(block.Selector);
            StartClass();

            var properties = block.Properties.Cast <NameValueProperty>();
            var firstN     = properties.Take(properties.Count() - 1);
            var last       = properties.LastOrDefault();

            foreach (var rule in firstN)
            {
                WriteRule(rule, lastRule: false);
            }

            if (last != null)
            {
                WriteRule(last, lastRule: true);
            }
            EndClass();
        }
コード例 #6
0
ファイル: Parser.cs プロジェクト: modulexcite/More
        internal static InnerMediaProperty ParseInnerMediaDirective(ParserStream stream)
        {
            var start = stream.Position;

            var media = new StringBuilder();

            stream.ScanUntil(media, '{');

            var mediaStr = media.ToString().Trim();

            if (mediaStr.IsNullOrEmpty())
            {
                Current.RecordError(ErrorType.Parser, Position.Create(start, stream.Position, Current.CurrentFilePath), "Expected media list");
                throw new StoppedParsingException();
            }

            var mediaQuery = MediaQueryParser.Parse(mediaStr, Position.Create(start, stream.Position, Current.CurrentFilePath));

            var props = ParseCssRules(InvalidSelector.Singleton, stream);

            var blockEquiv = new SelectorAndBlock(InvalidSelector.Singleton, props, null, start, stream.Position, Current.CurrentFilePath);

            return(new InnerMediaProperty(mediaQuery, blockEquiv, start, stream.Position, Current.CurrentFilePath));
        }
コード例 #7
0
        public static List <Block> Task(List <Block> statements)
        {
            var ret = new List <Block>();

            var mixins    = MapAndWarnDupe(statements.OfType <MixinBlock>(), s => s.Name, v => v);
            var variables = MapAndWarnDupe(statements.OfType <MoreVariable>(), s => s.Name, v => v.Value);

            var globalScope = new Scope(variables, mixins);

            Current.SetGlobalScope(globalScope);

            foreach (var charset in statements.OfType <CssCharset>())
            {
                ret.Add(charset.Bind(globalScope));
            }

            foreach (var import in statements.OfType <Model.Import>())
            {
                ret.Add(import.Bind(globalScope));
            }

            foreach (var block in statements.OfType <SelectorAndBlock>())
            {
                ret.Add(block.BindAndEvaluateMixins());
            }

            foreach (var animation in statements.OfType <KeyFramesBlock>())
            {
                var innerVariables = MapAndWarnDupe(animation.Variables, s => s.Name, s => s.Value);
                var innerScope     = globalScope.Push(innerVariables, new Dictionary <string, MixinBlock>(), animation);

                var frames = new List <KeyFrame>();
                foreach (var frame in animation.Frames)
                {
                    var blockEquivalent = new SelectorAndBlock(InvalidSelector.Singleton, frame.Properties, null, frame.Start, frame.Stop, frame.FilePath);
                    var bound           = blockEquivalent.BindAndEvaluateMixins(innerScope);

                    frames.Add(new KeyFrame(frame.Percentages.ToList(), bound.Properties.ToList(), frame.Start, frame.Stop, frame.FilePath));
                }

                ret.Add(new KeyFramesBlock(animation.Prefix, animation.Name, frames.ToList(), animation.Variables.ToList(), animation.Start, animation.Stop, animation.FilePath));
            }

            foreach (var media in statements.OfType <MediaBlock>())
            {
                var innerRet = new List <Block>();

                var innerVariable = MapAndWarnDupe(media.Blocks.OfType <MoreVariable>(), s => s.Name, v => v.Value);
                var innerScope    = globalScope.Push(innerVariable, new Dictionary <string, MixinBlock>(), media);

                foreach (var block in media.Blocks.OfType <SelectorAndBlock>())
                {
                    innerRet.Add(block.BindAndEvaluateMixins(innerScope));
                }

                ret.Add(new MediaBlock(media.MediaQuery.Bind(globalScope), innerRet, media.Start, media.Stop, media.FilePath));
            }

            foreach (var font in statements.OfType <FontFaceBlock>())
            {
                var blockEquiv = new SelectorAndBlock(InvalidSelector.Singleton, font.Properties, null, font.Start, font.Stop, font.FilePath);
                var bound      = blockEquiv.BindAndEvaluateMixins(globalScope);

                ret.Add(new FontFaceBlock(bound.Properties.ToList(), font.Start, font.Stop, font.FilePath));
            }

            return(ret);
        }
コード例 #8
0
ファイル: Includes.cs プロジェクト: modulexcite/More
        private static List <Block> Impl(List <Block> blocks, List <SelectorAndBlock> parent = null)
        {
            var ret = new List <Block>();

            var forLookup = blocks.OfType <SelectorAndBlock>().ToList();

            // At this point, unrolled blocks have only NameValue (unevaluated) and Includes
            foreach (var statement in blocks)
            {
                var block     = statement as SelectorAndBlock;
                var media     = statement as MediaBlock;
                var keyframes = statement as KeyFramesBlock;
                var fontface  = statement as FontFaceBlock;
                if (block == null && media == null && keyframes == null && fontface == null)
                {
                    ret.Add(statement);
                    continue;
                }

                if (block != null)
                {
                    var other    = block.Properties.Where(w => !(w is NameValueProperty || w is IncludeSelectorProperty)).ToList();
                    var simple   = block.Properties.OfType <NameValueProperty>().ToList();
                    var includes = block.Properties.OfType <IncludeSelectorProperty>();

                    var @override = new List <NameValueProperty>();

                    includes.Each(e =>
                    {
                        if (e.Overrides)
                        {
                            @override.AddRange(e.LookupMatch(forLookup, parent: parent));
                        }
                        else
                        {
                            simple.AddRange(e.LookupMatch(forLookup, parent: parent));
                        }
                    }
                                  );

                    var doubleDefined = false;
                    foreach (var e in @override.GroupBy(g => g.Name).Where(g => g.Count() > 1))
                    {
                        Current.RecordError(ErrorType.Compiler, block, "After resolving selector includes, the [" + e.Key + "] rule would be included as an override " + e.Count() + " times.");
                        doubleDefined = true;
                    }
                    if (doubleDefined)
                    {
                        throw new StoppedCompilingException();
                    }

                    foreach (var o in @override)
                    {
                        simple.RemoveAll(e => e.Name == o.Name);
                        simple.Add(o);
                    }

                    other.AddRange(simple);

                    ret.Add(new SelectorAndBlock(block.Selector, other, block.ResetContext, block.Start, block.Stop, block.FilePath));
                }

                if (media != null)
                {
                    var subBlocks = media.Blocks.ToList();
                    var copied    = Impl(subBlocks, parent: forLookup);

                    ret.Add(new MediaBlock(media.MediaQuery, copied, media.Start, media.Stop, media.FilePath));
                }

                if (keyframes != null)
                {
                    var frames = new List <KeyFrame>();

                    foreach (var frame in keyframes.Frames)
                    {
                        var blockEquiv = new SelectorAndBlock(InvalidSelector.Singleton, frame.Properties, null, frame.Start, frame.Stop, frame.FilePath);
                        var copied     = Impl(new List <Block>()
                        {
                            blockEquiv
                        }, parent: parent);

                        frames.Add(new KeyFrame(frame.Percentages.ToList(), ((SelectorAndBlock)copied[0]).Properties.ToList(), frame.Start, frame.Stop, frame.FilePath));
                    }

                    ret.Add(new KeyFramesBlock(keyframes.Prefix, keyframes.Name, frames, keyframes.Variables.ToList(), keyframes.Start, keyframes.Stop, keyframes.FilePath));
                }

                if (fontface != null)
                {
                    var blockEquiv = new SelectorAndBlock(InvalidSelector.Singleton, fontface.Properties, null, fontface.Start, fontface.Stop, fontface.FilePath);
                    var copied     = (SelectorAndBlock)Impl(new List <Block>()
                    {
                        blockEquiv
                    }, parent)[0];

                    ret.Add(new FontFaceBlock(copied.Properties.ToList(), copied.Start, copied.Stop, copied.FilePath));
                }
            }

            return(ret);
        }
コード例 #9
0
ファイル: Minify.cs プロジェクト: modulexcite/More
        public static List <Block> Task(List <Block> blocks)
        {
            var ret = new List <Block>();

            ret.AddRange(blocks.OfType <CssCharset>());
            ret.AddRange(blocks.OfType <Model.Import>().Select(s => new Model.Import(MinifyValue(s.ToImport), ForQuery(s.MediaQuery), s.Start, s.Stop, s.FilePath)));
            ret.AddRange(blocks.Where(w => w is SelectorAndBlock && ((SelectorAndBlock)w).IsReset));

            var remainder = blocks.Where(w => !ret.Contains(w));

            foreach (var statement in remainder)
            {
                var block = statement as SelectorAndBlock;
                if (block != null)
                {
                    var rules = new List <Property>();
                    foreach (var prop in block.Properties)
                    {
                        rules.Add(MinifyProperty(prop));
                    }

                    rules = MinifyPropertyList(rules).ToList();

                    ret.Add(new SelectorAndBlock(block.Selector, rules, block.ResetContext, block.Start, block.Stop, block.FilePath));
                    continue;
                }

                var media = statement as MediaBlock;
                if (media != null)
                {
                    var subStatements = Task(media.Blocks.ToList());
                    ret.Add(new MediaBlock(ForQuery(media.MediaQuery), subStatements, media.Start, media.Stop, media.FilePath));
                    continue;
                }

                var keyframes = statement as KeyFramesBlock;
                if (keyframes != null)
                {
                    var frames = new List <KeyFrame>();

                    // minify each frame
                    foreach (var frame in keyframes.Frames)
                    {
                        var blockEquiv = new SelectorAndBlock(InvalidSelector.Singleton, frame.Properties, null, frame.Start, frame.Stop, frame.FilePath);
                        var mind       = Task(new List <Block>()
                        {
                            blockEquiv
                        });
                        frames.Add(new KeyFrame(frame.Percentages.ToList(), ((SelectorAndBlock)mind[0]).Properties.ToList(), frame.Start, frame.Stop, frame.FilePath));
                    }

                    // collapse frames if rules are identical
                    var frameMap =
                        frames.ToDictionary(
                            d =>
                    {
                        using (var str = new StringWriter())
                            using (var css = new MinimalCssWriter(str))
                            {
                                foreach (var rule in d.Properties.Cast <NameValueProperty>())
                                {
                                    css.WriteRule(rule, lastRule: false);
                                }

                                return(str.ToString());
                            }
                    },
                            d => d
                            );

                    frames.Clear();
                    foreach (var frame in frameMap.GroupBy(k => k.Key))
                    {
                        var allPercents = new List <decimal>();
                        foreach (var f in frame)
                        {
                            allPercents.AddRange(f.Value.Percentages);
                        }

                        var urFrame = frame.First().Value;

                        frames.Add(new KeyFrame(allPercents, urFrame.Properties.ToList(), urFrame.Start, urFrame.Stop, urFrame.FilePath));
                    }

                    ret.Add(new KeyFramesBlock(keyframes.Prefix, keyframes.Name, frames, keyframes.Variables.ToList(), keyframes.Start, keyframes.Stop, keyframes.FilePath));
                    continue;
                }

                ret.Add(statement);
            }

            return(ret);
        }
コード例 #10
0
        private static IEnumerable <Block> Unroll(SelectorAndBlock block)
        {
            var ret   = new List <Block>();
            var props = new List <Property>();

            foreach (var prop in block.Properties)
            {
                var media  = prop as InnerMediaProperty;
                var nested = prop as NestedBlockProperty;
                if (media == null && nested == null)
                {
                    props.Add(prop);
                    continue;
                }

                if (nested != null)
                {
                    var inner      = Unroll(nested.Block);
                    var innerMedia = inner.OfType <MediaBlock>();
                    var other      = inner.Where(i => !(i is MediaBlock)).Cast <SelectorAndBlock>();

                    props.AddRange(other.Select(s => new NestedBlockProperty(s, s.Start, s.Stop)));

                    foreach (var m in innerMedia)
                    {
                        var selBlock =
                            new SelectorAndBlock(
                                block.Selector,
                                m.Blocks.Cast <SelectorAndBlock>().Select(s => new NestedBlockProperty(s, s.Start, s.Stop)),
                                null,
                                m.Start,
                                m.Stop,
                                m.FilePath
                                );

                        var newMedia =
                            new MediaBlock(
                                m.MediaQuery,
                                new List <Block> {
                            selBlock
                        },
                                m.Start,
                                m.Stop,
                                m.FilePath
                                );

                        ret.Add(newMedia);
                    }

                    continue;
                }

                var unrolled =
                    new MediaBlock(
                        media.MediaQuery,
                        new List <Block>
                {
                    new SelectorAndBlock(
                        block.Selector,
                        media.Block.Properties,
                        null,
                        -1,
                        -1,
                        media.FilePath
                        )
                },
                        -1,
                        -1,
                        media.FilePath
                        );

                ret.Add(unrolled);
            }

            ret.Add(new SelectorAndBlock(block.Selector, props, null, block.Start, block.Stop, block.FilePath));

            return(ret);
        }
コード例 #11
0
ファイル: Important.cs プロジェクト: modulexcite/More
        public static List <Block> Task(List <Block> blocks)
        {
            var ret = new List <Block>();

            foreach (var statement in blocks)
            {
                var block     = statement as SelectorAndBlock;
                var media     = statement as MediaBlock;
                var keyframes = statement as KeyFramesBlock;
                var fontface  = statement as FontFaceBlock;
                if (block == null && media == null && keyframes == null && fontface == null)
                {
                    ret.Add(statement);
                    continue;
                }

                if (block != null)
                {
                    var rules = new List <NameValueProperty>();

                    foreach (var group in block.Properties.Cast <NameValueProperty>().GroupBy(g => g.Name))
                    {
                        if (group.Count() == 1)
                        {
                            rules.Add(group.Single());
                        }
                        else
                        {
                            var important = group.SingleOrDefault(g => g.Value.IsImportant());

                            if (important == null)
                            {
                                Current.RecordWarning(ErrorType.Compiler, block, "More than one definition for [" + group.Key + "], did you mean for one to be !important?");

                                rules.AddRange(group);
                            }
                            else
                            {
                                rules.Add(important);
                            }
                        }
                    }

                    ret.Add(new SelectorAndBlock(block.Selector, rules, block.ResetContext, block.Start, block.Stop, block.FilePath));
                }

                if (media != null)
                {
                    var resolved = Task(media.Blocks.ToList());
                    ret.Add(new MediaBlock(media.MediaQuery, resolved, media.Start, media.Stop, media.FilePath));
                }

                if (keyframes != null)
                {
                    var frames = new List <KeyFrame>();
                    foreach (var frame in keyframes.Frames)
                    {
                        var blockEquiv = new SelectorAndBlock(InvalidSelector.Singleton, frame.Properties, null, frame.Start, frame.Stop, frame.FilePath);
                        var resolved   = Task(new List <Block>()
                        {
                            blockEquiv
                        });

                        frames.Add(new KeyFrame(frame.Percentages.ToList(), ((SelectorAndBlock)resolved[0]).Properties.ToList(), frame.Stop, frame.Stop, frame.FilePath));
                    }

                    ret.Add(new KeyFramesBlock(keyframes.Prefix, keyframes.Name, frames, keyframes.Variables.ToList(), keyframes.Start, keyframes.Stop, keyframes.FilePath));
                }

                if (fontface != null)
                {
                    var blockEquiv = new SelectorAndBlock(InvalidSelector.Singleton, fontface.Properties, null, fontface.Start, fontface.Stop, fontface.FilePath);
                    var resolved   = (SelectorAndBlock)Task(new List <Block>()
                    {
                        blockEquiv
                    })[0];

                    ret.Add(new FontFaceBlock(resolved.Properties.ToList(), fontface.Start, fontface.Stop, fontface.FilePath));
                }
            }

            return(ret);
        }
コード例 #12
0
        public static List <Block> Task(List <Block> blocks)
        {
            var ret = new List <Block>();

            foreach (var statement in blocks)
            {
                var block     = statement as SelectorAndBlock;
                var media     = statement as MediaBlock;
                var keyframes = statement as KeyFramesBlock;
                var fontface  = statement as FontFaceBlock;
                var import    = statement as Model.Import;
                if (block == null && media == null && keyframes == null && fontface == null && import == null)
                {
                    ret.Add(statement);
                    continue;
                }

                if (block != null)
                {
                    var processedRules = new List <NameValueProperty>();

                    // At this point, it is an error for any other type of rule to exist
                    foreach (var rule in block.Properties.Cast <NameValueProperty>())
                    {
                        var value = rule.Value.Evaluate();
                        while (value.NeedsEvaluate)
                        {
                            value = value.Evaluate();
                        }

                        if (!(value is ExcludeFromOutputValue))
                        {
                            processedRules.Add(new NameValueProperty(rule.Name, value, rule.Start, rule.Stop, rule.FilePath));
                        }
                    }

                    ret.Add(new SelectorAndBlock(block.Selector, processedRules, block.ResetContext, block.Start, block.Stop, block.FilePath));
                }

                if (media != null)
                {
                    var evaluated = Task(media.Blocks.ToList());

                    ret.Add(new MediaBlock(media.MediaQuery.Evaluate(), evaluated, media.Start, media.Stop, media.FilePath));
                }

                if (keyframes != null)
                {
                    var frames = new List <KeyFrame>();
                    foreach (var frame in keyframes.Frames)
                    {
                        var blockEquiv = new SelectorAndBlock(InvalidSelector.Singleton, frame.Properties, null, frame.Start, frame.Stop, frame.FilePath);
                        var evald      = Task(new List <Block>()
                        {
                            blockEquiv
                        });
                        frames.Add(new KeyFrame(frame.Percentages.ToList(), ((SelectorAndBlock)evald[0]).Properties.ToList(), frame.Start, frame.Stop, frame.FilePath));
                    }

                    ret.Add(new KeyFramesBlock(keyframes.Prefix, keyframes.Name, frames, keyframes.Variables.ToList(), keyframes.Start, keyframes.Stop, keyframes.FilePath));
                }

                if (fontface != null)
                {
                    var processedRules = new List <Property>();
                    foreach (var rule in fontface.Properties.Cast <NameValueProperty>())
                    {
                        var value = rule.Value.Evaluate();
                        while (value.NeedsEvaluate)
                        {
                            value = value.Evaluate();
                        }

                        if (!(value is ExcludeFromOutputValue))
                        {
                            processedRules.Add(new NameValueProperty(rule.Name, value, rule.Start, rule.Stop, rule.FilePath));
                        }
                    }

                    ret.Add(new FontFaceBlock(processedRules, fontface.Start, fontface.Stop, fontface.FilePath));
                }

                if (import != null)
                {
                    ret.Add(import.Evaluate());
                }
            }

            return(ret);
        }