public static string GetFullUrl(string text, string sourceFilename) { if (string.IsNullOrEmpty(text)) { return(null); } text = text.Trim(new[] { '\'', '"', '~' }); if (text.StartsWith("//", StringComparison.Ordinal)) { text = "http:" + text; } if (text.Contains("://") || text.StartsWith("data:", StringComparison.Ordinal)) { return(text); } if (String.IsNullOrEmpty(sourceFilename)) { return(null); } text = HttpUtility.UrlDecode(text); return(ProjectHelpers.ToAbsoluteFilePath(text, sourceFilename)); }
public async static Task <Dictionary <string, string> > WatchFiles(BundleDocument document, Func <string, bool, Task> updateBundle) { Dictionary <string, string> files = new Dictionary <string, string>(); if (document == null) { return(null); } await new BundleFileObserver().AttachFileObserver(document.FileName, document.FileName, updateBundle); foreach (string asset in document.BundleAssets) { string absolute = asset.Contains(":\\") ? asset : ProjectHelpers.ToAbsoluteFilePath(asset, document.FileName); if (File.Exists(absolute)) { if (!files.ContainsKey(absolute)) { files.Add(absolute, "/" + FileHelpers.RelativePath(ProjectHelpers.GetProjectFolder(document.FileName), asset)); await new BundleFileObserver().AttachFileObserver(absolute, document.FileName, updateBundle); } } else { EditorExtensionsPackage.DTE.ItemOperations.OpenFile(document.FileName); Logger.ShowMessage(String.Format(CultureInfo.CurrentCulture, "Bundle error: The file '{0}' doesn't exist", asset)); return(null); } } return(files); }
private static async Task <XDocument> MigrateBundle(XDocument doc, string fileName, string root, string folder) { string[] attrNames = new[] { "runOnBuild", "minify", "output" }; XElement bundle = doc.Descendants("bundle").FirstOrDefault(); string[] attributes = bundle.Attributes() .Where(a => attrNames.Contains(a.Name.ToString())) .Select(a => a.Name.ToString()) .ToArray(); if (attributes.Count() == 0) { return(doc); } IEnumerable <string> constituentFiles = from f in doc.Descendants("file") select ProjectHelpers.ToAbsoluteFilePath(f.Value, root, folder); BundleDocument newDoc = new BundleDocument(fileName, constituentFiles.ToArray()); if (attributes.Contains("runOnBuild")) { newDoc.RunOnBuild = bundle.Attribute("runOnBuild").Value.Equals("true", StringComparison.OrdinalIgnoreCase); } if (attributes.Contains("minify")) { newDoc.Minified = bundle.Attribute("minify").Value.Equals("true", StringComparison.OrdinalIgnoreCase); } return(await newDoc.WriteBundleRecipe()); }
private static void UpdateBundle(string changedFile, bool isBuild) { bool isDir = Directory.Exists(changedFile); string dir = isDir ? changedFile : ProjectHelpers.GetProjectFolder(changedFile); if (string.IsNullOrEmpty(dir) || !Directory.Exists(dir)) { return; } //if (dir.Contains(".")) //{ // dir = Path.GetDirectoryName(dir); //} foreach (string file in Directory.GetFiles(dir, "*" + _ext, SearchOption.AllDirectories)) { if (file.IndexOf("\\app_data\\", StringComparison.OrdinalIgnoreCase) > -1) { continue; } XmlDocument doc = GetXmlDocument(file); bool enabled = false; if (doc != null) { XmlNode bundleNode = doc.SelectSingleNode("//bundle"); if (bundleNode == null) { continue; } XmlNodeList nodes = doc.SelectNodes("//file"); foreach (XmlNode node in nodes) { string relative = node.InnerText; string absolute = ProjectHelpers.ToAbsoluteFilePath(relative, dir).Replace("/", "\\").Replace("\\\\", "\\"); if (changedFile != null && absolute.Equals(changedFile.Replace("\\\\", "\\"), StringComparison.OrdinalIgnoreCase)) { enabled = true; break; } } if (isBuild && bundleNode.Attributes["runOnBuild"] != null && bundleNode.Attributes["runOnBuild"].InnerText == "true") { enabled = true; } if (enabled) { WriteBundleFile(file, doc); } } } }
public override void Invoke() { string selection = _url.UrlString.Text; if (selection != null) { string filePath = ProjectHelpers.ToAbsoluteFilePath(selection); ApplyChanges(filePath); } }
public async static Task <Dictionary <string, string> > WatchFiles(BundleDocument document, Func <string, bool, Task> updateBundle, string bundleFile = null) { if (document == null) { return(null); } if (bundleFile == null && document.OutputDirectory != null) { bundleFile = ProjectHelpers.GetAbsolutePathFromSettings(document.OutputDirectory, Path.Combine(Path.GetDirectoryName(document.FileName), Path.GetFileNameWithoutExtension(document.FileName))); } Dictionary <string, string> files = new Dictionary <string, string>(); await new BundleFileObserver().AttachFileObserver(document, document.FileName, updateBundle); foreach (string asset in document.OriginalBundleAssets) { string absolute = asset.Contains(":\\") ? asset : ProjectHelpers.ToAbsoluteFilePath(asset, document.FileName); string absoluteActual = GetActualAsset(absolute); if (!File.Exists(absoluteActual)) { WebEssentialsPackage.DTE.ItemOperations.OpenFile(document.FileName); Logger.ShowMessage(String.Format(CultureInfo.CurrentCulture, "Bundle error: The file '{0}' doesn't exist", asset)); return(null); } if (!File.Exists(absolute)) { WebEssentialsPackage.DTE.ItemOperations.OpenFile(document.FileName); Logger.ShowMessage(String.Format(CultureInfo.CurrentCulture, "Bundle error: The file '{0}' doesn't exist", absolute)); return(null); } if (!files.ContainsKey(absoluteActual)) { if (Path.IsPathRooted(asset)) { files.Add(absolute, asset); } else { files.Add(absolute, FileHelpers.RelativePath(bundleFile, Path.GetFullPath(Path.Combine(Path.GetDirectoryName(document.FileName), asset)))); } await new BundleFileObserver().AttachFileObserver(document, absoluteActual, updateBundle); } } return(files); }
/// <summary> /// Update the following bundle file. /// </summary> /// <remarks> /// This method will update the bundle file only if the filename is actually a bundle file. /// Otherwise does nothing. /// It also skips the app_data folder. /// </remarks> /// <param name="rootFolder">The root folder of the project.</param> /// <param name="changedFile">The bundle file to update.</param> /// <param name="isBuild">Is this a build time event.</param> private static void UpdateBundle(string rootFolder, string changedFile, bool isBuild) { if (changedFile.IndexOf("\\app_data\\", StringComparison.OrdinalIgnoreCase) > -1) { return; } if (Path.GetExtension(changedFile) != _ext) { return; } XmlDocument doc = GetXmlDocument(changedFile); bool enabled = false; if (doc != null) { XmlNode bundleNode = doc.SelectSingleNode("//bundle"); if (bundleNode == null) { return; } XmlNodeList nodes = doc.SelectNodes("//file"); foreach (XmlNode node in nodes) { string relative = node.InnerText; string absolute = ProjectHelpers.ToAbsoluteFilePath(relative, rootFolder).Replace("/", "\\").Replace("\\\\", "\\"); if (absolute.Equals(changedFile.Replace("\\\\", "\\"), StringComparison.OrdinalIgnoreCase)) { enabled = true; break; } } if (isBuild && bundleNode.Attributes != null && bundleNode.Attributes["runOnBuild"] != null && bundleNode.Attributes["runOnBuild"].InnerText == "true") { enabled = true; } if (enabled) { WriteBundleFile(changedFile, doc); } } }
protected override bool Execute(uint commandId, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut) { _path = _path.TrimStart('~').Trim(); string openFile = EditorExtensionsPackage.DTE.ActiveDocument.FullName; string projectFolder = ProjectHelpers.GetProjectFolder(openFile); string absolute = ProjectHelpers.ToAbsoluteFilePath(_path, projectFolder); if (File.Exists(absolute)) { OpenFileInPreviewTab(absolute); return(true); } EditorExtensionsPackage.DTE.StatusBar.Text = "Couldn't find " + _path; return(false); }
public static SpriteDocument FromFile(string fileName) { XDocument doc = XDocument.Load(fileName); string root = ProjectHelpers.GetProjectFolder(fileName); string folder = Path.GetDirectoryName(root); var imageFiles = from f in doc.Descendants("file") select ProjectHelpers.ToAbsoluteFilePath(f.Value, root, folder); SpriteDocument sprite = new SpriteDocument(fileName, imageFiles.ToArray()); sprite.Optimize = doc.Descendants("optimize").First().Value.Equals("true", StringComparison.OrdinalIgnoreCase); sprite.IsVertical = doc.Descendants("orientation").First().Value.Equals("vertical", StringComparison.OrdinalIgnoreCase); sprite.FileExtension = doc.Descendants("outputType").First().Value; return(sprite); }
private async static Threading.Task ObserveBundleFileObjects(string file) { XmlDocument doc = await GetXmlDocument(file); if (doc == null) { return; } XmlNode bundleNode = doc.SelectSingleNode("//bundle"); if (bundleNode == null) { return; } XmlNodeList nodes = doc.SelectNodes("//file"); foreach (XmlNode node in nodes) { await new BundleFileWatcher().AttachFileObserverEvent(ProjectHelpers.ToAbsoluteFilePath(node.InnerText, file)); } }
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 UpdateBundle(string changedFile, bool isBuild) { string absolutePath = ProjectHelpers.FixAbsolutePath(changedFile); bool isDir = Directory.Exists(changedFile); string dir = isDir ? changedFile : ProjectHelpers.GetProjectFolder(changedFile); if (string.IsNullOrEmpty(dir) || !Directory.Exists(dir)) { return; } foreach (string file in Directory.EnumerateFiles(dir, "*" + _ext, SearchOption.AllDirectories)) { if (_ignoreFolders.Any(p => file.Contains("\\" + p + "\\"))) { continue; } XmlDocument doc = await GetXmlDocument(file); if (doc == null) { continue; } XmlNode bundleNode = doc.SelectSingleNode("//bundle"); if (bundleNode == null) { continue; } string baseDir = Path.GetDirectoryName(file); if ((changedFile != null && doc.SelectNodes("//file").Cast <XmlNode>().Any(x => absolutePath == ProjectHelpers.ToAbsoluteFilePath(x.InnerText, dir, baseDir))) || (isBuild && bundleNode.Attributes["runOnBuild"] != null && bundleNode.Attributes["runOnBuild"].InnerText == "true")) { WriteBundleFile(file, doc).DoNotWait("reading " + file + " file"); } } }
private static void WriteBundleFile(string filePath, 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("\\"))) { MessageBox.Show("The 'output' attribute should contain a file name without a path", "Web Essentials"); return; } Dictionary <string, string> files = new Dictionary <string, string>(); string extension = Path.GetExtension(filePath.Replace(_ext, string.Empty)); 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, ProjectHelpers.GetProjectFolder(filePath)).Replace("\\\\", "\\"); } if (File.Exists(absolute)) { if (!files.ContainsKey(absolute)) { files.Add(absolute, node.InnerText); } } else { string error = string.Format("Bundle error: The file '{0}' doesn't exist", node.InnerText); _dte.ItemOperations.OpenFile(filePath); MessageBox.Show(error, "Web Essentials"); return; } } string bundlePath = outputAttr != null?Path.Combine(Path.GetDirectoryName(filePath), outputAttr.InnerText) : filePath.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.GetBoolean(WESettings.Keys.GenerateJavaScriptSourceMaps)) { sb.AppendLine("///#source 1 1 " + files[file]); } sb.AppendLine(File.ReadAllText(file)); } if (!File.Exists(bundlePath) || File.ReadAllText(bundlePath) != sb.ToString()) { ProjectHelpers.CheckOutFileFromSourceControl(bundlePath); using (StreamWriter writer = new StreamWriter(bundlePath, false, new UTF8Encoding(true))) { writer.Write(sb.ToString()); Logger.Log("Updating bundle: " + Path.GetFileName(bundlePath)); } MarginBase.AddFileToProject(filePath, bundlePath); if (bundleNode.Attributes["minify"] != null || bundleNode.Attributes["minify"].InnerText == "true") { WriteMinFile(filePath, bundlePath, sb.ToString(), extension); } } }
public override void Invoke() { string filePath = ProjectHelpers.ToAbsoluteFilePath(_path); ApplyChanges(filePath); }
private static string GetRelativeFolder(string url) { int end = Math.Max(0, url.LastIndexOf('/')); return(ProjectHelpers.ToAbsoluteFilePath(url.Substring(0, end))); }
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); }