コード例 #1
0
ファイル: ImportStatement.cs プロジェクト: rytmis/lesson.net
        protected override IEnumerable <LessNode> EvaluateCore(EvaluationContext context)
        {
            string EvaluateFilePath(Expression expr)
            {
                if (expr is LessString str)
                {
                    return(str.GetUnquotedValue());
                }

                if (expr is Url url)
                {
                    return(EvaluateFilePath(url.Content));
                }

                return(expr.ToString());
            }

            // Import resolution takes care of relative paths regardless of the
            // rewrite setting, so while evaluating the import URL, we turn the
            // rewrite setting off.
            bool rewrite = context.RewriteRelativeUrls;

            context.RewriteRelativeUrls = false;
            var evaluatedUrl = Url.EvaluateSingle <Expression>(context);

            context.RewriteRelativeUrls = rewrite;

            var filePath = EvaluateFilePath(evaluatedUrl);

            bool isExplicitCssImport = options.HasFlag(ImportOptions.Css);

            if (isExplicitCssImport || !filePath.IsLocalFilePath())
            {
                return(new[] { this });
            }

            var extension = Path.GetExtension(filePath);

            bool isCssFile            = extension == ".css";
            bool isExplicitLessImport = options.HasFlag(ImportOptions.Less);
            bool isInlineImport       = options.HasFlag(ImportOptions.Inline);

            if (isCssFile && !isExplicitLessImport && !isInlineImport)
            {
                return(new[] {
                    new ImportStatement(
                        evaluatedUrl,
                        options,
                        mediaQueries.Select(mq => mq.EvaluateSingle <MediaQuery>(context))),
                });
            }

            var actualImportPath = string.IsNullOrEmpty(extension)
                                ? Path.ChangeExtension(filePath, "less")
                                : filePath;


            var importResults = GetImportResults(options.HasFlag(ImportOptions.Optional));

            if (importResults == null)
            {
                return(Enumerable.Empty <LessNode>());
            }

            if (mediaQueries.Any())
            {
                return(new[] { new MediaBlock(mediaQueries, new RuleBlock(importResults)).EvaluateSingle <MediaBlock>(context) });
            }

            return(importResults);

            IEnumerable <Statement> GetImportResults(bool optional)
            {
                if (context.SeenImport(actualImportPath))
                {
                    return(Enumerable.Empty <Statement>());
                }

                if (!options.HasFlag(ImportOptions.Reference))
                {
                    context.NoteImport(actualImportPath);
                }

                using (context.EnterImportScope(actualImportPath)) {
                    try {
                        if (isCssFile && isInlineImport)
                        {
                            return(new Statement[] { new InlineCssImportStatement(context.GetFileContent()) });
                        }


                        return(context
                               .ParseCurrentStylesheet(isReference: options.HasFlag(ImportOptions.Reference))
                               .Evaluate(context)
                               .OfType <Statement>()
                               .ToList());
                    } catch (IOException ex) {
                        if (optional)
                        {
                            return(null);
                        }

                        throw new EvaluationException($"Failed to import {filePath}", ex);
                    }
                }
            }
        }