private async static Task <string> CombineFiles(Dictionary <string, string> files, string extension, BundleDocument bundle, string bundleFile)
        {
            StringBuilder sb = new StringBuilder();

            foreach (string file in files.Keys)
            {
                if (extension.Equals(".js", StringComparison.OrdinalIgnoreCase) && WESettings.Instance.JavaScript.GenerateSourceMaps)
                {
                    sb.AppendLine("///#source 1 1 " + files[file]);
                }

                var source = await FileHelpers.ReadAllTextRetry(file);

                if (extension.Equals(".css", StringComparison.OrdinalIgnoreCase))
                {
                    // If the bundle is in the same folder as the CSS,
                    // or if does not have URLs, no need to normalize.
                    if (Path.GetDirectoryName(file) != Path.GetDirectoryName(bundleFile) &&
                        source.IndexOf("url(", StringComparison.OrdinalIgnoreCase) > 0 &&
                        bundle.AdjustRelativePaths)
                    {
                        source = CssUrlNormalizer.NormalizeUrls(
                            tree: new CssParser().Parse(source, true),
                            targetFile: bundleFile,
                            oldBasePath: file
                            );
                    }
                }

                sb.AppendLine(source);
            }
            return(sb.ToString());
        }
Exemple #2
0
        public async static Task <bool> MakeBundle(BundleDocument document, string bundleFile, Func <string, bool, Task> updateBundle)
        {
            // filePath must end in ".targetExtension.bundle"
            string extension = Path.GetExtension(Path.GetFileNameWithoutExtension(document.FileName));

            if (string.IsNullOrEmpty(extension))
            {
                Logger.Log("Skipping bundle file " + document.FileName + " without extension.  Bundle files must end with the output extension, followed by '.bundle'.");
                return(false);
            }

            Dictionary <string, string> files = await WatchFiles(document, updateBundle, bundleFile);

            string combinedContent = await CombineFiles(files, extension, document, bundleFile);

            bool bundleChanged = !File.Exists(bundleFile) || await FileHelpers.ReadAllTextRetry(bundleFile) != combinedContent;

            if (bundleChanged)
            {
                if (!ProjectHelpers.CheckOutFileFromSourceControl(bundleFile))
                {
                    throw new Exception("There was a problem checking out the file: " + bundleFile);
                }

                await FileHelpers.WriteAllTextRetry(bundleFile, combinedContent);

                Logger.Log("Web Essentials: Updated bundle: " + Path.GetFileName(bundleFile));
            }

            ProjectHelpers.AddFileToProject(document.FileName, bundleFile);

            return(bundleChanged);
        }
Exemple #3
0
        public async void Navigate(object sender, EventArgs e)
        {
            ErrorTask task = (ErrorTask)sender;

            if (MessageBox.Show(Question, "Web Essentials", MessageBoxButtons.YesNo) == DialogResult.Yes)
            {
                if (!File.Exists(_file))
                {
                    return;
                }

                string html = await FileHelpers.ReadAllTextRetry(_file);

                int index = html.IndexOf("</head>", StringComparison.OrdinalIgnoreCase);

                if (index > -1)
                {
                    EditorExtensionsPackage.DTE.ItemOperations.OpenFile(_file);
                    _extension.ErrorList.Tasks.Remove(task);

                    AddMetaTag(index);
                    return;
                }
            }
        }
        private async Task <CompilerResult> ProcessResult(Process process, string errorText, string sourceFileName, string targetFileName, string mapFileName)
        {
            string result  = "";
            bool   success = false;
            IEnumerable <CompilerError> errors = null;

            try
            {
                if (process.ExitCode == 0)
                {
                    if (!string.IsNullOrEmpty(targetFileName) && File.Exists(targetFileName))
                    {
                        result = await FileHelpers.ReadAllTextRetry(targetFileName);
                    }

                    success = true;
                }
                else
                {
                    errors = ParseErrors(errorText);
                }
            }
            catch (FileNotFoundException missingFileException)
            {
                Logger.Log(ServiceName + ": " + Path.GetFileName(targetFileName) + " compilation failed. " + missingFileException.Message);
            }

            if (success)
            {
                var renewedResult = await PostProcessResult(result, sourceFileName, targetFileName, mapFileName);

                if (!ReferenceEquals(result, renewedResult))
                {
                    await FileHelpers.WriteAllTextRetry(targetFileName, renewedResult);

                    result = renewedResult;
                }
            }

            var compilerResult = await CompilerResultFactory.GenerateResult(
                sourceFileName : sourceFileName,
                targetFileName : targetFileName,
                mapFileName : mapFileName,
                isSuccess : success,
                result : result,
                errors : errors
                ) as CompilerResult;

            if (!success)
            {
                var firstError = compilerResult.Errors.Where(e => e != null).Select(e => e.Message).FirstOrDefault();

                if (firstError != null)
                {
                    Logger.Log(ServiceName + ": " + Path.GetFileName(sourceFileName) + " compilation failed: " + firstError);
                }
            }

            return(compilerResult);
        }
        protected async override Task RtlVariantHandler(CompilerResult result)
        {
            if (!WESettings.Instance.Css.RtlCss || result.RtlTargetFileName == null)
            {
                return;
            }

            string value = PostProcessResult(result.RtlResult, result.RtlTargetFileName, result.RtlSourceFileName);

            // Write output file
            if (result.RtlTargetFileName != null && (MinifyInPlace || !File.Exists(result.RtlTargetFileName) ||
                                                     value != await FileHelpers.ReadAllTextRetry(result.RtlTargetFileName)))
            {
                ProjectHelpers.CheckOutFileFromSourceControl(result.RtlTargetFileName);
                await FileHelpers.WriteAllTextRetry(result.RtlTargetFileName, value);

                ProjectHelpers.AddFileToProject(result.RtlSourceFileName, result.RtlTargetFileName);
            }

            // Write map file
            if (GenerateSourceMap && (!File.Exists(result.RtlMapFileName) ||
                                      result.RtlResultMap != await FileHelpers.ReadAllTextRetry(result.RtlMapFileName)))
            {
                ProjectHelpers.CheckOutFileFromSourceControl(result.RtlMapFileName);
                await FileHelpers.WriteAllTextRetry(result.RtlMapFileName, result.RtlResultMap);

                ProjectHelpers.AddFileToProject(result.RtlTargetFileName, result.RtlMapFileName);
            }
        }
Exemple #6
0
        private async Task <dynamic> ValidateResult(Process process, string outputFile, string errorText)
        {
            string result    = null;
            var    isSuccess = false;
            IEnumerable <CompilerError> errors = null;

            try
            {
                if (process.ExitCode == 0)
                {
                    if (!string.IsNullOrEmpty(outputFile) && File.Exists(outputFile))
                    {
                        result = await FileHelpers.ReadAllTextRetry(outputFile);
                    }
                    isSuccess = true;
                }
                else
                {
                    errors = ParseErrors(errorText);
                }
            }
            catch (FileNotFoundException missingFileException)
            {
                Logger.Log(ServiceName + ": " + Path.GetFileName(outputFile) + " compilation failed. " + missingFileException.Message);
            }

            return(new
            {
                Result = result,
                IsSuccess = isSuccess,
                Errors = errors
            });
        }
        // Don't try-catch this method: We need to "address" all the bugs,
        // which may occur as the (node.js-based) service implement changes.
        private async Task <CompilerResult> ProcessResult(CompilerResult result, bool onlyPreview, string sourceFileName, string targetFileName)
        {
            if (result == null)
            {
                Logger.Log(ServiceName + ": " + Path.GetFileName(sourceFileName) + " compilation failed: The service failed to respond to this request\n\t\t\tPossible cause: Syntax Error!");
                return(await CompilerResultFactory.GenerateResult(sourceFileName, targetFileName));
            }
            if (!result.IsSuccess)
            {
                var firstError = result.Errors.Where(e => e != null).Select(e => e.Message).FirstOrDefault();

                if (firstError != null)
                {
                    Logger.Log(firstError);
                }

                return(result);
            }

            string resultString = PostProcessResult(result.Result, result.TargetFileName, result.SourceFileName);

            if (!onlyPreview)
            {
                // Write output file
                if (result.TargetFileName != null && (MinifyInPlace || !File.Exists(result.TargetFileName) ||
                                                      resultString != await FileHelpers.ReadAllTextRetry(result.TargetFileName)))
                {
                    ProjectHelpers.CheckOutFileFromSourceControl(result.TargetFileName);
                    await FileHelpers.WriteAllTextRetry(result.TargetFileName, resultString);

                    if (!(this is ILintCompiler))
                    {
                        ProjectHelpers.AddFileToProject(result.SourceFileName, result.TargetFileName);
                    }
                }

                // Write map file
                if (GenerateSourceMap && (!File.Exists(result.MapFileName) ||
                                          result.ResultMap != await FileHelpers.ReadAllTextRetry(result.MapFileName)))
                {
                    ProjectHelpers.CheckOutFileFromSourceControl(result.MapFileName);
                    await FileHelpers.WriteAllTextRetry(result.MapFileName, result.ResultMap);

                    if (!(this is ILintCompiler))
                    {
                        ProjectHelpers.AddFileToProject(result.TargetFileName, result.MapFileName);
                    }
                }

                await RtlVariantHandler(result);
            }

            return(CompilerResult.UpdateResult(result, resultString));
        }
        private async static Task <string> CombineFiles(Dictionary <string, string> files, string extension, BundleDocument bundle, string bundleFile)
        {
            StringBuilder sb = new StringBuilder();

            foreach (string file in files.Keys)
            {
                string actualFile = file;

                if (extension.Equals(".js", StringComparison.OrdinalIgnoreCase) && WESettings.Instance.JavaScript.GenerateSourceMaps)
                {
                    sb.AppendLine("///#source 1 1 " + files[file]);
                }

                var source = await FileHelpers.ReadAllTextRetry(actualFile);

                if (extension.Equals(".css", StringComparison.OrdinalIgnoreCase))
                {
                    // If the bundle is in the same folder as the CSS,
                    // or if does not have URLs, no need to normalize.
                    if (Path.GetDirectoryName(actualFile) != Path.GetDirectoryName(bundleFile) &&
                        source.IndexOf("url(", StringComparison.OrdinalIgnoreCase) > 0 &&
                        bundle.AdjustRelativePaths)
                    {
                        source = CssUrlNormalizer.NormalizeUrls(
                            tree: new CssParser().Parse(source, true),
                            targetFile: bundleFile,
                            oldBasePath: actualFile
                            );
                    }
                }
                else if (Path.GetExtension(file).Equals(".ts", StringComparison.OrdinalIgnoreCase))
                {
                    // If it is a Type Script include, we might want to alter the define(... at the start of the script to specify the resource location.
                    if (source.StartsWith("define([\"require\", \"exports\""))
                    {
                        string moduleName = files[file];

                        moduleName = Path.Combine(Path.GetDirectoryName(moduleName), Path.GetFileNameWithoutExtension(moduleName)).Replace('\\', '/');

                        if (moduleName.ToLower().StartsWith(WESettings.Instance.JavaScript.RootDirectory.ToLower()))
                        {
                            moduleName = moduleName.Substring(WESettings.Instance.JavaScript.RootDirectory.Length);
                        }

                        source = source.Replace("define([\"require\", \"exports\"", "define(\"" + moduleName + "\", [\"require\", \"exports\"");
                    }
                }

                sb.AppendLine(source);
            }
            return(sb.ToString());
        }
Exemple #9
0
        private async Task <IEnumerable <CssSourceMapNode> > ProcessSourceMaps()
        {
            ParseItem  item       = null;
            Selector   selector   = null;
            StyleSheet styleSheet = null;
            int        start;
            var        fileContents      = "";
            var        result            = new List <CssSourceMapNode>();
            var        contentCollection = new HashSet <string>();

            foreach (var node in MapNodes)
            {
                // Cache source file contents.
                if (!contentCollection.Contains(node.SourceFilePath))
                {
                    if (!File.Exists(node.SourceFilePath)) // Lets say someone deleted the reference file.
                    {
                        continue;
                    }

                    fileContents = await FileHelpers.ReadAllTextRetry(node.SourceFilePath);

                    contentCollection.Add(node.SourceFilePath);

                    styleSheet = _parser.Parse(fileContents, false);
                }

                start  = fileContents.NthIndexOfCharInString('\n', node.OriginalLine);
                start += node.OriginalColumn;

                item = styleSheet.ItemAfterPosition(start);

                if (item == null)
                {
                    continue;
                }

                selector = item.FindType <Selector>();

                if (selector == null)
                {
                    continue;
                }

                node.OriginalSelector = selector;

                result.Add(node);
            }

            return(result);
        }
 private async static Task <XmlDocument> GetXmlDocument(string filePath)
 {
     try
     {
         XmlDocument xmlDocument = new XmlDocument();
         xmlDocument.LoadXml((await FileHelpers.ReadAllTextRetry(filePath)).Trim());
         return(xmlDocument);
     }
     catch (Exception)
     {
         Logger.Log(Path.GetFileName(filePath) + " is not a valid Web Essentials bundle file. Ignoring file.");
         return(null);
     }
 }
Exemple #11
0
        public async static Task <CssCompilerResult> GenerateResult(string sourceFileName, string targetFileName, string mapFileName, bool isSuccess, string result, IEnumerable <CompilerError> errors)
        {
            CssCompilerResult compilerResult = new CssCompilerResult(sourceFileName, targetFileName, isSuccess, result, errors);

            if (mapFileName == null)
            {
                return(null);
            }

            var extension = Path.GetExtension(sourceFileName).TrimStart('.');

            compilerResult.SourceMap = CssSourceMap.Create(await FileHelpers.ReadAllTextRetry(targetFileName),
                                                           await FileHelpers.ReadAllTextRetry(mapFileName),
                                                           Path.GetDirectoryName(targetFileName),
                                                           Mef.GetContentType(extension));

            return(compilerResult);
        }
        ///<summary>Gets the value of the "main" entry in a directory's package.json, or null if it doesn't exist or is invalid.</summary>
        private async static Task <string> GetPackageMain(string directory)
        {
            var packageFile = Path.Combine(directory, "package.json");

            if (!File.Exists(packageFile))
            {
                return(null);
            }
            try
            {
                var json = JObject.Parse(await FileHelpers.ReadAllTextRetry(packageFile).ConfigureAwait(false));
                return(json.Value <string>("main"));
            }
            catch (Exception ex)
            {
                Logger.Log("An error occurred while reading " + packageFile + ": " + ex.Message);
                return(null);
            }
        }
Exemple #13
0
        public async static Task <CompilerResult> GenerateResult(string sourceFileName, string targetFileName, string mapFileName, bool isSuccess, string result, string resultMap, IEnumerable <CompilerError> errors, bool hasResult = false, string rtlSourceFileName = "", string rtlTargetFileName = "", string rtlMapFileName = "", string rtlResult = "", string rtlResultMap = "")
        {
            CompilerResult instance;

            mapFileName = mapFileName ?? targetFileName + ".map";

            if (result == null && File.Exists(targetFileName))
            {
                result = await FileHelpers.ReadAllTextRetry(targetFileName);
            }

            if (targetFileName != null && Path.GetExtension(targetFileName).Equals(".css", StringComparison.OrdinalIgnoreCase))
            {
                instance = CssCompilerResult.GenerateResult(sourceFileName, targetFileName, mapFileName, isSuccess, result, resultMap, errors, rtlSourceFileName, rtlTargetFileName, rtlMapFileName, rtlResult, rtlResultMap, hasResult);
            }
            else
            {
                instance = CompilerResult.GenerateResult(sourceFileName, targetFileName, mapFileName, isSuccess, result, resultMap, errors, hasResult);
            }

            return(instance);
        }
Exemple #14
0
        private async Task HandleRtlCss(CompilerResult result)
        {
            string value = result.RtlResult;

            // Write output file
            if (result.RtlTargetFileName != null && (MinifyInPlace || !File.Exists(result.RtlTargetFileName) ||
                                                     value != await FileHelpers.ReadAllTextRetry(result.RtlTargetFileName)))
            {
                ProjectHelpers.CheckOutFileFromSourceControl(result.RtlTargetFileName);
                await FileHelpers.WriteAllTextRetry(result.RtlTargetFileName, value);

                ProjectHelpers.AddFileToProject(result.RtlSourceFileName, result.RtlTargetFileName);
            }

            // Write map file
            if (GenerateSourceMap && (!File.Exists(result.RtlMapFileName) ||
                                      result.RtlResultMap != await FileHelpers.ReadAllTextRetry(result.RtlMapFileName)))
            {
                ProjectHelpers.CheckOutFileFromSourceControl(result.RtlMapFileName);
                await FileHelpers.WriteAllTextRetry(result.RtlMapFileName, result.RtlResultMap);

                ProjectHelpers.AddFileToProject(result.RtlTargetFileName, result.RtlMapFileName);
            }
        }
        public async Task <CompilerResult> CompileAsync(string sourceFileName, string targetFileName)
        {
            if (RequireMatchingFileName &&
                Path.GetFileName(targetFileName) != Path.GetFileNameWithoutExtension(sourceFileName) + TargetExtension &&
                Path.GetFileName(targetFileName) != Path.GetFileNameWithoutExtension(sourceFileName) + ".min" + TargetExtension)
            {
                throw new ArgumentException(ServiceName + " cannot compile to a targetFileName with a different name.  Only the containing directory can be different.", "targetFileName");
            }

            var mapFileName = GetMapFileName(sourceFileName, targetFileName);

            var scriptArgs = GetArguments(sourceFileName, targetFileName, mapFileName);

            var errorOutputFile = Path.GetTempFileName();

            var cmdArgs = string.Format("\"{0}\" \"{1}\"", NodePath, CompilerPath);

            cmdArgs = string.Format("/c \"{0} {1} > \"{2}\" 2>&1\"", cmdArgs, scriptArgs, errorOutputFile);

            ProcessStartInfo start = new ProcessStartInfo("cmd")
            {
                WindowStyle      = ProcessWindowStyle.Hidden,
                WorkingDirectory = Path.GetDirectoryName(sourceFileName),
                Arguments        = cmdArgs,
                UseShellExecute  = false,
                CreateNoWindow   = true
            };

            try
            {
                ProjectHelpers.CheckOutFileFromSourceControl(targetFileName);

                mapFileName = mapFileName ?? targetFileName + ".map";

                if (GenerateSourceMap)
                {
                    ProjectHelpers.CheckOutFileFromSourceControl(mapFileName);
                }

                using (var process = await start.ExecuteAsync())
                {
                    if (targetFileName != null)
                    {
                        await MoveOutputContentToCorrectTarget(targetFileName);
                    }

                    return(await ProcessResult(
                               process,
                               (await FileHelpers.ReadAllTextRetry(errorOutputFile)).Trim(),
                               sourceFileName,
                               targetFileName,
                               mapFileName
                               ));
                }
            }
            finally
            {
                File.Delete(errorOutputFile);

                if (!GenerateSourceMap)
                {
                    File.Delete(mapFileName);
                }
            }
        }
        public static async Task <BundleDocument> FromFile(string fileName)
        {
            var    extension = Path.GetExtension(fileName).TrimStart('.').ToLowerInvariant();
            string root      = ProjectHelpers.GetProjectFolder(fileName);
            string folder    = Path.GetDirectoryName(root);

            if (folder == null || root == null)
            {
                return(null);
            }

            XDocument doc = null;

            string contents = await FileHelpers.ReadAllTextRetry(fileName);

            try
            {
                doc = XDocument.Parse(contents);
            }
            catch (XmlException)
            {
                return(null);
            }

            // Migrate old bundles
            doc = await MigrateBundle(doc, fileName, root, folder);

            if (doc == null)
            {
                return(null);
            }

            XElement             element          = null;
            IEnumerable <string> constituentFiles = from f in doc.Descendants("file")
                                                    select ProjectHelpers.ToAbsoluteFilePath(f.Value, root, folder);

            BundleDocument bundle = new BundleDocument(fileName, constituentFiles.ToArray());

            element = doc.Descendants("minify").FirstOrDefault();

            if (element != null)
            {
                bundle.Minified = element.Value.Equals("true", StringComparison.OrdinalIgnoreCase);
            }

            element = doc.Descendants("runOnBuild").FirstOrDefault();

            if (element != null)
            {
                bundle.RunOnBuild = element.Value.Equals("true", StringComparison.OrdinalIgnoreCase);
            }

            if (extension == "css")
            {
                element = doc.Descendants("adjustRelativePaths").FirstOrDefault();

                if (element != null)
                {
                    bundle.AdjustRelativePaths = element.Value.Equals("true", StringComparison.OrdinalIgnoreCase);
                }
            }

            element = doc.Descendants("outputDirectory").FirstOrDefault();

            if (element != null)
            {
                bundle.OutputDirectory = element.Value;
            }

            return(bundle);
        }
Exemple #17
0
        public static async Task <BundleDocument> FromFile(string fileName)
        {
            string root   = ProjectHelpers.GetProjectFolder(fileName);
            string folder = Path.GetDirectoryName(root);

            if (folder == null || root == null)
            {
                return(null);
            }

            XDocument doc = null;

            string contents = await FileHelpers.ReadAllTextRetry(fileName);

            try
            {
                doc = XDocument.Parse(contents);
            }
            catch (XmlException)
            {
                return(null);
            }

            // Migrate old bundles
            doc = await MigrateBundle(doc, fileName, root, folder);

            if (doc == null)
            {
                return(null);
            }

            XElement             element          = null;
            IEnumerable <string> rawConstituents  = doc.Descendants("file").Select(s => s.Value);
            IEnumerable <string> constituentFiles = ProjectHelpers.GetBundleConstituentFiles(rawConstituents, root, folder, fileName);

            if (constituentFiles.Count() > 0)
            {
                BundleDocument bundle = new BundleDocument(fileName, constituentFiles.ToArray())
                {
                    OriginalBundleAssets = new List <string>(rawConstituents)
                };

                element = doc.Descendants("minify").FirstOrDefault();

                if (element != null)
                {
                    bundle.Minified = element.Value.Equals("true", StringComparison.OrdinalIgnoreCase);
                }

                element = doc.Descendants("runOnBuild").FirstOrDefault();

                if (element != null)
                {
                    bundle.RunOnBuild = element.Value.Equals("true", StringComparison.OrdinalIgnoreCase);
                }

                if (bundle.isCss)
                {
                    element = doc.Descendants("adjustRelativePaths").FirstOrDefault();

                    if (element != null)
                    {
                        bundle.AdjustRelativePaths = element.Value.Equals("true", StringComparison.OrdinalIgnoreCase);
                    }
                }

                element = doc.Descendants("outputDirectory").FirstOrDefault();

                if (element != null)
                {
                    bundle.OutputDirectory = element.Value;
                }

                return(bundle);
            }
            else
            {
                return(null);
            }
        }
        private async static Threading.Task WriteBundleFile(string bundleFilePath, XmlDocument doc)
        {
            XmlNode bundleNode = doc.SelectSingleNode("//bundle");

            if (bundleNode == null)
            {
                return;
            }

            XmlNode outputAttr = bundleNode.Attributes["output"];

            if (outputAttr != null && (outputAttr.InnerText.Contains("/") || outputAttr.InnerText.Contains("\\")))
            {
                Logger.ShowMessage(String.Format(CultureInfo.CurrentCulture, "The 'output' attribute should contain a file name without a path; '{0}' is not valid", outputAttr.InnerText));
                return;
            }

            Dictionary <string, string> files = new Dictionary <string, string>();

            // filePath must end in ".targetExtension.bundle"
            string extension = Path.GetExtension(Path.GetFileNameWithoutExtension(bundleFilePath));

            if (string.IsNullOrEmpty(extension))
            {
                Logger.Log("Skipping bundle file " + bundleFilePath + " without extension.  Bundle files must end with the output extension, followed by '.bundle'.");
                return;
            }

            XmlNodeList nodes = doc.SelectNodes("//file");

            foreach (XmlNode node in nodes)
            {
                string absolute;

                if (node.InnerText.Contains(":\\"))
                {
                    absolute = node.InnerText;
                }
                else
                {
                    absolute = ProjectHelpers.ToAbsoluteFilePath(node.InnerText, bundleFilePath);
                }

                if (File.Exists(absolute))
                {
                    if (!files.ContainsKey(absolute))
                    {
                        files.Add(absolute, node.InnerText);
                    }
                }
                else
                {
                    _dte.ItemOperations.OpenFile(bundleFilePath);
                    Logger.ShowMessage(String.Format(CultureInfo.CurrentCulture, "Bundle error: The file '{0}' doesn't exist", node.InnerText));

                    return;
                }
            }

            string bundleSourcePath = outputAttr != null?Path.Combine(Path.GetDirectoryName(bundleFilePath), outputAttr.InnerText) : bundleFilePath.Replace(_ext, string.Empty);

            StringBuilder sb = new StringBuilder();

            foreach (string file in files.Keys)
            {
                //if (extension.Equals(".css", StringComparison.OrdinalIgnoreCase))
                //{
                //    sb.AppendLine("/*#source " + files[file] + " */");
                //}
                if (extension.Equals(".js", StringComparison.OrdinalIgnoreCase) && WESettings.Instance.JavaScript.GenerateSourceMaps)
                {
                    sb.AppendLine("///#source 1 1 " + files[file]);
                }

                if (!File.Exists(file))
                {
                    continue;
                }

                await new BundleFileWatcher().AttachFileObserverEvent(file);

                var source = await FileHelpers.ReadAllTextRetry(file);

                if (extension.Equals(".css", StringComparison.OrdinalIgnoreCase))
                {
                    // If the bundle is in the same folder as the CSS,
                    // or if does not have URLs, no need to normalize.
                    if (Path.GetDirectoryName(file) != Path.GetDirectoryName(bundleSourcePath) &&
                        source.IndexOf("url(", StringComparison.OrdinalIgnoreCase) > 0 &&
                        WESettings.Instance.Css.AdjustRelativePaths)
                    {
                        source = CssUrlNormalizer.NormalizeUrls(
                            tree: new CssParser().Parse(source, true),
                            targetFile: bundleSourcePath,
                            oldBasePath: file
                            );
                    }
                }

                sb.AppendLine(source);
            }

            bool bundleChanged = !File.Exists(bundleSourcePath) || await FileHelpers.ReadAllTextRetry(bundleSourcePath) != sb.ToString();

            if (bundleChanged)
            {
                ProjectHelpers.CheckOutFileFromSourceControl(bundleSourcePath);
                await FileHelpers.WriteAllTextRetry(bundleSourcePath, sb.ToString());

                Logger.Log("Web Essentials: Updated bundle: " + Path.GetFileName(bundleSourcePath));
            }

            ProjectHelpers.AddFileToProject(bundleFilePath, bundleSourcePath);

            if (bundleNode.Attributes["minify"] != null && bundleNode.Attributes["minify"].InnerText == "true")
            {
                await WriteMinFile(bundleSourcePath, extension, bundleChanged);
            }
        }
        private async static Threading.Task MakeBundleAsync(string extension)
        {
            var items = GetSelectedItems(extension);

            if (items.Count() == 0)
            {
                return;
            }

            StringBuilder sb = new StringBuilder();

            foreach (ProjectItem item in items)
            {
                if (!File.Exists(item.FileNames[1]))
                {
                    continue;
                }

                string content = await FileHelpers.ReadAllTextRetry(item.FileNames[1]);

                sb.AppendLine(content);
            }

            ProjectItem firstItem = items.SkipWhile(x => x.FileNames[1] != null).FirstOrDefault();

            if (firstItem == null || string.IsNullOrEmpty(firstItem.FileNames[1]))
            {
                return;
            }

            string dir = Path.GetDirectoryName(firstItem.FileNames[1]);

            if (!Directory.Exists(dir))
            {
                return;
            }

            string bundleFile = Microsoft.VisualBasic.Interaction.InputBox("Specify the name of the bundle", "Web Essentials", "bundle1");

            if (string.IsNullOrEmpty(bundleFile))
            {
                return;
            }

            if (!bundleFile.EndsWith(extension + _ext, StringComparison.OrdinalIgnoreCase))
            {
                bundleFile += extension + _ext;
            }

            string bundlePath = Path.Combine(dir, bundleFile);

            if (File.Exists(bundlePath))
            {
                Logger.ShowMessage("The bundle file already exists.");
                return;
            }

            await Dispatcher.CurrentDispatcher.BeginInvoke(new Action(async() =>
                                                                      await WriteBundleRecipe(bundlePath, items, Path.ChangeExtension(bundleFile, null))), // Remove the final ".bundle" extension.
                                                           DispatcherPriority.ApplicationIdle, null);
        }
Exemple #20
0
 // Overridden to work around SASS bug
 // TODO: Remove when https://github.com/hcatlin/libsass/issues/242 is fixed
 protected async virtual Task <string> ReadMapFile(string sourceMapFileName)
 {
     return(await FileHelpers.ReadAllTextRetry(sourceMapFileName));
 }
Exemple #21
0
        // A very ugly hack for a very ugly bug: https://github.com/hcatlin/libsass/issues/324
        // Remove this and its caller in previous method, when it is fixed in original repo
        // and https://github.com/andrew/node-sass/ is released with the fix.
        // Overwriting all positions belonging to original/source file.
        private async Task <IEnumerable <CssSourceMapNode> > CorrectionsForScss(string cssFileContents)
        {
            // Sort collection for generated file.
            var sortedForGenerated = MapNodes.OrderBy(x => x.GeneratedLine)
                                     .ThenBy(x => x.GeneratedColumn)
                                     .ToList();

            ParseItem      item = null;
            Selector       selector = null;
            SimpleSelector simple = null;
            StyleSheet     styleSheet = null, cssStyleSheet = null;
            int            start = 0, indexInCollection, targetDepth;
            string         fileContents = null, simpleText = "";
            var            result            = new List <CssSourceMapNode>();
            var            contentCollection = new HashSet <string>(); // So we don't have to read file for each map item.
            var            parser            = new CssParser();

            cssStyleSheet = parser.Parse(cssFileContents, false);

            foreach (var node in MapNodes)
            {
                // Cache source file contents.
                if (!contentCollection.Contains(node.SourceFilePath))
                {
                    if (!File.Exists(node.SourceFilePath)) // Lets say someone deleted the reference file.
                    {
                        continue;
                    }

                    fileContents = await FileHelpers.ReadAllTextRetry(node.SourceFilePath);

                    contentCollection.Add(node.SourceFilePath);

                    styleSheet = _parser.Parse(fileContents, false);
                }

                start  = cssFileContents.NthIndexOfCharInString('\n', node.GeneratedLine);
                start += node.GeneratedColumn;

                item = cssStyleSheet.ItemAfterPosition(start);

                if (item == null)
                {
                    continue;
                }

                selector = item.FindType <Selector>();
                simple   = item.FindType <SimpleSelector>();

                if (selector == null || simple == null)
                {
                    continue;
                }

                simpleText = simple.Text;

                indexInCollection = sortedForGenerated.FindIndex(e => e.Equals(node));//sortedForGenerated.IndexOf(node);

                targetDepth = 0;

                for (int i = indexInCollection;
                     i >= 0 && node.GeneratedLine == sortedForGenerated[i].GeneratedLine;
                     targetDepth++, --i)
                {
                    ;
                }

                start  = fileContents.NthIndexOfCharInString('\n', node.OriginalLine);
                start += node.OriginalColumn;

                item = styleSheet.ItemAfterPosition(start);

                while (item.TreeDepth > targetDepth)
                {
                    item = item.Parent;
                }

                // selector = item.FindType<RuleSet>().Selectors.First();

                RuleSet       rule;
                ScssRuleBlock scssRuleBlock = item as ScssRuleBlock;

                rule = scssRuleBlock == null ? item as RuleSet : scssRuleBlock.RuleSets.FirstOrDefault();

                if (rule == null)
                {
                    continue;
                }

                // Because even on the same TreeDepth, there may be mulitple ruleblocks
                // and the selector names may include & or other symbols which are diff
                // fromt he generated counterpart, here is the guess work
                item = rule.Children.FirstOrDefault(r => r is Selector && r.Text.Trim() == simpleText) as Selector;

                selector = item == null ? null : item as Selector;

                if (selector == null)
                {
                    // One more try: look for the selector in neighboring rule blocks then skip.
                    selector = rule.Children.Where(r => r is RuleBlock)
                               .SelectMany(r => (r as RuleBlock).Children
                                           .Where(s => s is RuleSet)
                                           .Select(s => (s as RuleSet).Selectors.FirstOrDefault(sel => sel.Text.Trim() == simpleText)))
                               .FirstOrDefault();

                    if (selector == null)
                    {
                        continue;
                    }
                }

                node.OriginalLine   = fileContents.Substring(0, selector.Start).Count(s => s == '\n');
                node.OriginalColumn = fileContents.GetLineColumn(selector.Start, node.OriginalLine);

                result.Add(node);
            }

            return(result);
        }