Exemple #1
0
        /// <summary>
        /// End tags handler
        /// </summary>
        /// <param name="context">Markup parsing context</param>
        /// <param name="tagName">Tag name</param>
        private void EndTagHandler(MarkupParsingContext context, string tagName)
        {
            XmlNodeType previousNodeType = _currentNodeType;
            string      previousText     = _currentText;

            _currentNodeType = XmlNodeType.EndTag;
            _currentText     = string.Empty;

            XmlMinificationOutputWriter output = _output;

            if (_settings.CollapseTagsWithoutContent && previousNodeType == XmlNodeType.StartTag &&
                previousText.Length == 0)
            {
                if (output.TransformLastStartTagToEmptyTag(_settings.RenderEmptyTagsWithSpace))
                {
                    output.Flush();
                    return;
                }
            }

            if (_settings.MinifyWhitespace && previousNodeType == XmlNodeType.Text &&
                (_endTagBeforeText || _emptyTagBeforeText))
            {
                output.RemoveLastWhitespaceItems();
            }

            // Add end tag to buffer
            output.Write("</");
            output.Write(tagName);
            output.Write(">");

            output.Flush();
        }
Exemple #2
0
        /// <summary>
        /// Start tags handler
        /// </summary>
        /// <param name="context">Markup parsing context</param>
        /// <param name="tagName">Tag name</param>
        /// <param name="attributes">List of attributes</param>
        private void StartTagHandler(MarkupParsingContext context, string tagName,
                                     List <XmlAttribute> attributes)
        {
            XmlNodeType previousNodeType = _currentNodeType;

            _currentNodeType = XmlNodeType.StartTag;
            _currentText     = string.Empty;

            XmlMinificationOutputWriter output = _output;

            if (_settings.MinifyWhitespace && previousNodeType == XmlNodeType.Text &&
                (_startTagBeforeText || _endTagBeforeText || _emptyTagBeforeText ||
                 _ignoredFragmentBeforeText || _xmlDeclarationBeforeText ||
                 _processingInstructionBeforeText || _doctypeBeforeText))
            {
                output.RemoveLastWhitespaceItems();
            }

            output.Flush();

            output.Write("<");
            output.Write(tagName);
            WriteAttributes(attributes);
            output.Write(">");
        }
Exemple #3
0
        /// <summary>
        /// CDATA sections handler
        /// </summary>
        /// <param name="context">Markup parsing context</param>
        /// <param name="cdataText">CDATA text</param>
        private void CdataSectionHandler(MarkupParsingContext context, string cdataText)
        {
            _currentNodeType = XmlNodeType.CdataSection;

            XmlMinificationOutputWriter output = _output;

            output.Write("<![CDATA[");
            output.Write(cdataText);
            output.Write("]]>");
        }
Exemple #4
0
        /// <summary>
        /// Comments handler
        /// </summary>
        /// <param name="context">Markup parsing context</param>
        /// <param name="commentText">Comment text</param>
        private void CommentHandler(MarkupParsingContext context, string commentText)
        {
            if (!_settings.RemoveXmlComments)
            {
                _currentNodeType = XmlNodeType.Comment;

                XmlMinificationOutputWriter output = _output;
                output.Write("<!--");
                output.Write(commentText);
                output.Write("-->");
            }
        }
Exemple #5
0
        /// <summary>
        /// Document type declaration handler
        /// </summary>
        /// <param name="context">Markup parsing context</param>
        /// <param name="doctype">Document type declaration</param>
        private void DoctypeDelegateHandler(MarkupParsingContext context, string doctype)
        {
            _currentNodeType = XmlNodeType.Doctype;

            XmlMinificationOutputWriter output = _output;

            if (_settings.MinifyWhitespace)
            {
                output.RemoveLastWhitespaceItems();
            }

            output.Write(Utils.CollapseWhitespace(doctype));
            output.Flush();
        }
Exemple #6
0
        /// <summary>
        /// Writes a attributes to buffer
        /// </summary>
        /// <param name="attributes">List of attributes</param>
        private void WriteAttributes(List <XmlAttribute> attributes)
        {
            int attributeCount = attributes.Count;

            for (int attributeIndex = 0; attributeIndex < attributeCount; attributeIndex++)
            {
                XmlAttribute attribute             = attributes[attributeIndex];
                string       encodedAttributeValue = XmlAttributeValueHelpers.Encode(attribute.Value);

                XmlMinificationOutputWriter output = _output;
                output.Write(" ");
                output.Write(attribute.Name);
                output.Write("=\"");
                output.Write(encodedAttributeValue);
                output.Write("\"");
            }
        }
Exemple #7
0
        /// <summary>
        /// Ignored fragments handler
        /// </summary>
        /// <param name="context">Markup parsing context</param>
        /// <param name="fragment">Ignored fragment</param>
        private void IgnoredFragmentHandler(MarkupParsingContext context, string fragment)
        {
            _currentNodeType = XmlNodeType.IgnoredFragment;

            XmlMinificationOutputWriter output = _output;

            if (_settings.MinifyWhitespace)
            {
                output.RemoveLastWhitespaceItems();
            }

            if (fragment.Length > 0)
            {
                output.Write(fragment);
                output.Flush();
            }
        }
Exemple #8
0
        /// <summary>
        /// XML declaration handler
        /// </summary>
        /// <param name="context">Markup parsing context</param>
        /// <param name="attributes">List of attributes</param>
        private void XmlDeclarationHandler(MarkupParsingContext context, List <XmlAttribute> attributes)
        {
            _currentNodeType = XmlNodeType.XmlDeclaration;

            XmlMinificationOutputWriter output = _output;

            if (_settings.MinifyWhitespace)
            {
                output.RemoveLastWhitespaceItems();
            }

            output.Write("<?xml");
            WriteAttributes(attributes);
            output.Write("?>");

            output.Flush();
        }
Exemple #9
0
        /// <summary>
        /// Processing instruction handler
        /// </summary>
        /// <param name="context">Markup parsing context</param>
        /// <param name="instructionName">Instruction name</param>
        /// <param name="attributes">List of attributes</param>
        private void ProcessingInstructionHandler(MarkupParsingContext context, string instructionName,
                                                  List <XmlAttribute> attributes)
        {
            _currentNodeType = XmlNodeType.ProcessingInstruction;

            XmlMinificationOutputWriter output = _output;

            if (_settings.MinifyWhitespace)
            {
                output.RemoveLastWhitespaceItems();
            }

            output.Write("<?");
            output.Write(instructionName);
            WriteAttributes(attributes);
            output.Write("?>");

            output.Flush();
        }
Exemple #10
0
        /// <summary>
        /// Constructs instance of XML minifier
        /// </summary>
        /// <param name="settings">XML minification settings</param>
        /// <param name="logger">Logger</param>
        public XmlMinifier(XmlMinificationSettings settings = null, ILogger logger = null)
        {
            _settings  = settings ?? new XmlMinificationSettings();
            _logger    = logger ?? new NullLogger();
            _xmlParser = new XmlParser(new XmlParsingHandlers
            {
                XmlDeclaration        = XmlDeclarationHandler,
                ProcessingInstruction = ProcessingInstructionHandler,
                Doctype         = DoctypeDelegateHandler,
                Comment         = CommentHandler,
                CdataSection    = CdataSectionHandler,
                StartTag        = StartTagHandler,
                EndTag          = EndTagHandler,
                EmptyTag        = EmptyTagHandler,
                Text            = TextHandler,
                IgnoredFragment = IgnoredFragmentHandler
            });

            _output          = new XmlMinificationOutputWriter(48);
            _errors          = new List <MinificationErrorInfo>();
            _currentNodeType = XmlNodeType.Unknown;
            _currentText     = string.Empty;
        }
Exemple #11
0
        /// <summary>
        /// Empty tags handler
        /// </summary>
        /// <param name="context">Markup parsing context</param>
        /// <param name="tagName">Tag name</param>
        /// <param name="attributes">List of attributes</param>
        private void EmptyTagHandler(MarkupParsingContext context, string tagName,
                                     List <XmlAttribute> attributes)
        {
            XmlNodeType previousNodeType = _currentNodeType;

            _currentNodeType = XmlNodeType.EmptyTag;
            _currentText     = string.Empty;

            XmlMinificationOutputWriter output = _output;

            if (_settings.MinifyWhitespace && previousNodeType == XmlNodeType.Text &&
                (_startTagBeforeText || _endTagBeforeText || _emptyTagBeforeText))
            {
                output.RemoveLastWhitespaceItems();
            }

            output.Write("<");
            output.Write(tagName);
            WriteAttributes(attributes);
            output.Write(_settings.RenderEmptyTagsWithSpace ? " />" : "/>");

            output.Flush();
        }
Exemple #12
0
        /// <summary>
        /// Text handler
        /// </summary>
        /// <param name="context">Markup parsing context</param>
        /// <param name="text">Text</param>
        private void TextHandler(MarkupParsingContext context, string text)
        {
            XmlNodeType previousNodeType = _currentNodeType;

            _currentNodeType = XmlNodeType.Text;

            XmlMinificationOutputWriter output = _output;

            if (previousNodeType == XmlNodeType.Text)
            {
                _currentText = text;
                output.Write(text);

                return;
            }

            _xmlDeclarationBeforeText        = false;
            _processingInstructionBeforeText = false;
            _doctypeBeforeText         = false;
            _startTagBeforeText        = false;
            _endTagBeforeText          = false;
            _emptyTagBeforeText        = false;
            _ignoredFragmentBeforeText = false;

            switch (previousNodeType)
            {
            case XmlNodeType.StartTag:
                _startTagBeforeText = true;
                break;

            case XmlNodeType.EndTag:
                _endTagBeforeText = true;
                break;

            case XmlNodeType.EmptyTag:
                _emptyTagBeforeText = true;
                break;

            case XmlNodeType.IgnoredFragment:
                _ignoredFragmentBeforeText = true;
                break;

            case XmlNodeType.XmlDeclaration:
                _xmlDeclarationBeforeText = true;
                break;

            case XmlNodeType.ProcessingInstruction:
                _processingInstructionBeforeText = true;
                break;

            case XmlNodeType.Doctype:
                _doctypeBeforeText = true;
                break;
            }

            if (_settings.MinifyWhitespace)
            {
                if (context.Position == 0)
                {
                    // Processing starting whitespace
                    text = text.TrimStart(null);
                }
                else if (context.Position + text.Length == context.Length)
                {
                    // Processing ending whitespace
                    text = text.TrimEnd(null);
                }
                else if (_xmlDeclarationBeforeText || _processingInstructionBeforeText || _doctypeBeforeText)
                {
                    // Processing whitespace, that followed after
                    // the XML declaration, processing instruction
                    // or document type declaration
                    if (string.IsNullOrWhiteSpace(text))
                    {
                        text = string.Empty;
                    }
                }
            }

            _currentText = text;

            if (text.Length > 0)
            {
                output.Write(text);
            }
        }
Exemple #13
0
        /// <summary>
        /// Minify XML content
        /// </summary>
        /// <param name="content">XML content</param>
        /// <param name="fileContext">File context</param>
        /// <param name="encoding">Text encoding</param>
        /// <param name="generateStatistics">Flag for whether to allow generate minification statistics</param>
        /// <returns>Minification result</returns>
        public MarkupMinificationResult Minify(string content, string fileContext, Encoding encoding,
                                               bool generateStatistics)
        {
            MinificationStatistics statistics = null;
            string        cleanedContent      = Utils.RemoveByteOrderMark(content);
            string        minifiedContent     = string.Empty;
            var           stringBuilderPool   = StringBuilderPool.Shared;
            StringBuilder sb = null;
            XmlMinificationOutputWriter output = _output;
            var errors = new List <MinificationErrorInfo>();

            lock (_minificationSynchronizer)
            {
                try
                {
                    if (generateStatistics)
                    {
                        statistics = new MinificationStatistics(encoding);
                        statistics.Init(cleanedContent);
                    }

                    sb = stringBuilderPool.Rent(cleanedContent.Length);
                    output.StringBuilder = sb;

                    _xmlParser.Parse(cleanedContent);

                    output.Flush();

                    if (_errors.Count == 0)
                    {
                        minifiedContent = output.ToString();

                        if (generateStatistics)
                        {
                            statistics.End(minifiedContent);
                        }
                    }
                }
                catch (MarkupParsingException e)
                {
                    WriteError(LogCategoryConstants.XmlParsingError, e.Message, fileContext,
                               e.LineNumber, e.ColumnNumber, e.SourceFragment);
                }
                finally
                {
                    output.Clear();
                    output.StringBuilder = null;
                    stringBuilderPool.Return(sb);
                    _currentNodeType = XmlNodeType.Unknown;
                    _currentText     = string.Empty;

                    errors.AddRange(_errors);
                    _errors.Clear();
                }

                if (errors.Count == 0)
                {
                    _logger.Info(LogCategoryConstants.XmlMinificationSuccess,
                                 string.Format(Strings.SuccesMessage_MarkupMinificationComplete, "XML"),
                                 fileContext, statistics);
                }
            }

            return(new MarkupMinificationResult(minifiedContent, errors, statistics));
        }