예제 #1
0
        // returns the new current node
        void DoTailTag(HeaderFooter tag)
        {
            // find self or parent with matching header tag
            ContainerNode searchNode = _curNode;

            while (searchNode != null && searchNode.Header.NameLowerCased != tag.NameLowerCased)
            {
                searchNode = searchNode.ParentNode;
            }

            // if no matching head found
            if (searchNode == null)
            {
                return;
            }

            // add to current node
            searchNode.Footer = tag;

            if (_noInnerTagNodes.Contains(tag.NameLowerCased))
            {
                // convert whatever children happened to be parsed, into a single text node
                // used primarily to fix <script> nodes that have < and > in them
                searchNode.ChildNodes.Clear();

                // We used to have option to parse JavaScriptDocument but now we will do that manually because it was too confusing.
                searchNode.AddChild(new TextNode(searchNode.Source, searchNode.Header.End, searchNode.Footer.Begin));
            }

            // return current node to parent
            _curNode = searchNode.ParentNode;
        }
예제 #2
0
        void DoLiteral(int i)
        {
            // create node for it
            ConsumeText(_currentToken.Begin);
            string name = _currentToken.Type.ToString();

            name = name.Substring(0, name.Length - 7);               // strip 'Literal'
            var literalHeader = new HeaderFooter(_currentNode.Source, _currentToken.Begin, _currentToken.End, name, HeaderFooterType.Single);
            var literalNode   = new ContainerNode(_source, literalHeader, new Dictionary <string, string>());

            _currentNode.AddChild(literalNode);
            _beginOfTextNode = _currentToken.End;

            IdentifyContainerNode(i, literalNode);
        }
예제 #3
0
        // builds/returns a phantom root node for string content
        ContainerNode BuildPhantomRootNode()
        {
            string source = _source;
            // create header at begining, footer at end
            HeaderFooter header = new HeaderFooter(source, 0, 0, "script", HeaderFooterType.Head);
            HeaderFooter footer = new HeaderFooter(source, source.Length, source.Length, "script", HeaderFooterType.Tail);

            // make node
            ContainerNode rootNode = new ContainerNode(_source, header, new Dictionary <string, string> {
                { "type", "text/javascript" }
            });

            rootNode.Footer = footer;
            return(rootNode);
        }
예제 #4
0
        ContainerNode TryParse()
        {
            // find root node
            _curIndex = _source.IndexOf('<');
            if (_curIndex < 0)
            {
                throw new FormatException("No root node found.");
            }

            // setup root node
            HeaderFooter rootHeader = ParseHeaderFooter();

            if (rootHeader.Type == HeaderFooterType.Tail)
            {
                throw new FormatException("root node cannot be ending tag.");
            }

            ContainerNode root = new ContainerNode(_source, rootHeader);

            if (rootHeader.Type != HeaderFooterType.Single)
            {
                _curNode = root;
            }
            _curIndex = rootHeader.End;

            //
            while (_curIndex < _source.Length && _curNode != null)
            {
                if (_source[_curIndex] != '<')
                {
                    ConsumeText();
                }
                else if (CurrentIndexPointsAt("<!--"))
                {
                    ConsumeComment();
                }
                else
                {
                    ConsumeTag();
                }
            }

            return(root);
        }
예제 #5
0
        /// <summary>
        /// Consumes the tag head, tail, or single at curIndex
        /// </summary>
        void ConsumeTag()
        {
            HeaderFooter headerFooter = ParseHeaderFooter();

            switch (headerFooter.Type)
            {
            case HeaderFooterType.Single:
            case HeaderFooterType.Head:
                DoStarterTag(headerFooter);
                break;

            case HeaderFooterType.Tail:
                DoTailTag(headerFooter);
                break;

            default:
                throw new FormatException("screwy tag type");
            }

            _curIndex = headerFooter.End;
        }
예제 #6
0
        int DoKeyword(int i)
        {
            JsToken next = (i + 1) < _tokenList.Count ? _tokenList[i + 1] : null;

            // create node for it
            ConsumeText(_currentToken.Begin);
            var keywordHeader = new HeaderFooter(_source, _currentToken.Begin, _currentToken.End, _currentToken.Text, HeaderFooterType.Single);
            var keywordNode   = new ContainerNode(_source, keywordHeader, new Dictionary <string, string>());

            _currentNode.AddChild(keywordNode);
            _beginOfTextNode = _currentToken.End;

            // name function
            if (_currentToken.Text == "function" && next != null && next.Type == JsTokenType.Identifier)
            {
                IdentifyNode(keywordNode, next.Text);
                ++i;                 // skip id token
                _beginOfTextNode = next.End;
            }

            return(i);
        }
예제 #7
0
        // returns the new current node
        void DoStarterTag(HeaderFooter tag)
        {
            // Head & Single
            // new node
            ContainerNode n = new ContainerNode(_source, tag);

            // create parent-child relationship
            _curNode.AddChild(n);

            // force some node types to be single
            bool isSingle = tag.Type == HeaderFooterType.Single ||
                            _emptyTags.Contains(tag.Name);

            // if forced-empty node has a tailtag, it will be ignored

            // !! Not doing anything special about illegally embeded nodes such as
            //		<p>first paragraph <p> new paragraph, close previous <p> another paragraph

            if (!isSingle)
            {
                _curNode = n;
            }
        }
예제 #8
0
        void MoveDownIntoSubSection(int i)
        {
            _openTokensIndexStack.Push(i);

            // add previous text node
            ConsumeText(_currentToken.Begin);

            // add new node
            var name      = BracketName(_currentToken.Text);
            var header    = new HeaderFooter(_currentNode.Source, _currentToken.Begin, _currentToken.End, "block", HeaderFooterType.Head);
            var blockNode = new ContainerNode(_source, header, new Dictionary <string, string> {
                { "class", name }
            });

            _currentNode.AddChild(blockNode);

            IdentifyContainerNode(i, blockNode);

            // set new text-node start
            _beginOfTextNode = _currentToken.End;

            // move down to new node
            _currentNode = blockNode;
        }
예제 #9
0
 /// <summary>
 /// Constructs a Container that uses attributes provided by the input dictionary.
 /// </summary>
 internal ContainerNode(string source, HeaderFooter header, Dictionary <string, string> attr)
     : base(source, header.Begin, header.Name)
 {
     this.Header      = header;
     this._attributes = attr;
 }
예제 #10
0
 /// <summary>
 /// Constructs a Container that uses the attributes embedded in the tag header.
 /// </summary>
 internal ContainerNode(string source, HeaderFooter header)
     : base(source, header.Begin, header.Name)
 {
     this.Header = header;
 }