/// <summary> /// Gets or Adds a V3InlineSourceMap into the current bundle context /// </summary> /// <param name="bundleContext"></param> /// <param name="sourceMapType"></param> /// <returns></returns> public static V3DeferredSourceMap GetSourceMapFromContext(this BundleContext bundleContext, SourceMapType sourceMapType) { var key = typeof(V3DeferredSourceMap).Name; object ctx; if (bundleContext.Items.TryGetValue(key, out ctx)) { return((V3DeferredSourceMap)ctx); } //not in the context so add it var sb = new StringBuilder(); var sourceMapWriter = new Utf8StringWriter(sb); var inlineSourceMap = new V3DeferredSourceMap((V3SourceMap)SourceMapFactory.Create(sourceMapWriter, V3SourceMap.ImplementationName), sb, sourceMapType); bundleContext.Items[key] = inlineSourceMap; return(inlineSourceMap); }
private void ProcessJavaScript(IList <InputGroup> inputGroups, SwitchParser switchParser, string outputPath, SymbolMap symbolMap, Encoding outputEncoding) { var settings = switchParser.JSSettings; TextWriter mapWriter = null; ISourceMap sourceMap = null; try { // if we want a symbols map, we need to set it up now if (symbolMap != null && !settings.PreprocessOnly) { // if we specified the path, use it. Otherwise just use the output path with // ".map" appended to the end. Eg: output.js => output.js.map var symbolMapPath = symbolMap.Path.IsNullOrWhiteSpace() ? outputPath + ".map" : symbolMap.Path; // create the map writer and the source map implementation. // look at the Name attribute and implement the proper one. // the encoding needs to be UTF-8 WITHOUT a BOM or it won't work. if (!FileWriteOperation(symbolMapPath, switchParser.Clobber, () => { mapWriter = new StreamWriter(symbolMapPath, false, new UTF8Encoding(false)); sourceMap = SourceMapFactory.Create(mapWriter, symbolMap.Name); if (sourceMap != null) { // if we get here, the symbol map now owns the stream and we can null it out so // we don't double-close it mapWriter = null; settings.SymbolsMap = sourceMap; // copy some property values sourceMap.SourceRoot = symbolMap.SourceRoot.IfNullOrWhiteSpace(null); sourceMap.SafeHeader = symbolMap.SafeHeader.GetValueOrDefault(false); // start the package sourceMap.StartPackage(outputPath, symbolMapPath); } return(true); })) { // could not write file Log.LogError(Strings.CouldNotWriteOutputFile, symbolMapPath); } } // save the original term settings. We'll make sure to set this back again // for the last item in the group, but we'll make sure it's TRUE for all the others. var originalTermSetting = settings.TermSemicolons; var currentSourceOrigin = SourceOrigin.Project; var parser = new JSParser(); parser.CompilerError += (sender, ea) => { // if the input group isn't project, then we only want to report sev-0 errors. // regardless, don't show any errors that have a severity lower (greater numeric value) // than the warning level specified. if ((currentSourceOrigin == SourceOrigin.Project || ea.Error.Severity == 0) && ea.Error.Severity <= switchParser.WarningLevel) { LogContextError(ea.Error); } }; var outputBuilder = new StringBuilder(8192); using (var writer = new StringWriter(outputBuilder, CultureInfo.InvariantCulture)) { for (var inputGroupIndex = 0; inputGroupIndex < inputGroups.Count; ++inputGroupIndex) { var inputGroup = inputGroups[inputGroupIndex]; currentSourceOrigin = inputGroup.Origin; // for all but the last item, we want the term-semicolons setting to be true. // but for the last entry, set it back to its original value settings.TermSemicolons = inputGroupIndex < inputGroups.Count - 1 ? true : originalTermSetting; if (settings.PreprocessOnly) { parser.EchoWriter = writer; if (inputGroupIndex > 0) { // not the first group, so output the appropriate newline // sequence before we output the group. writer.Write(settings.LineTerminator); } } else { // not preprocess-only, so make sure the echo writer is null parser.EchoWriter = null; } // parse the input var block = parser.Parse(inputGroup.Source, settings); if (block != null && !settings.PreprocessOnly) { if (inputGroupIndex > 0) { // not the first group, so output the appropriate newline // sequence before we output the group. writer.Write(settings.LineTerminator); } // minify the AST to the output if (settings.Format == JavaScriptFormat.JSON) { if (!JSONOutputVisitor.Apply(writer, block, settings)) { Log.LogError(Strings.InvalidJSONOutput); } } else { OutputVisitor.Apply(writer, block, settings); } } } } // write output if (!Log.HasLoggedErrors) { if (!FileWriteOperation(outputPath, switchParser.Clobber, () => { using (var writer = new StreamWriter(outputPath, false, outputEncoding)) { // write the combined minified code writer.Write(outputBuilder.ToString()); if (!settings.PreprocessOnly) { // give the map (if any) a chance to add something settings.SymbolsMap.IfNotNull(m => m.EndFile( writer, settings.LineTerminator)); } } return(true); })) { // could not write file Log.LogError(Strings.CouldNotWriteOutputFile, outputPath); } } else { Log.LogWarning(Strings.DidNotMinify, outputPath, Strings.ThereWereErrors); if (File.Exists(outputPath)) { File.Delete(outputPath); } } } finally { if (sourceMap != null) { mapWriter = null; settings.SymbolsMap = null; sourceMap.EndPackage(); sourceMap.Dispose(); } if (mapWriter != null) { mapWriter.Close(); } } }
public void SetUp() { _factory = new SourceMapFactory(); }