blob: 5c78c3e6d07d93b191c8a22755fca8c3a1c569de [file] [log] [blame]
/**
* Copyright 2010 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Author: mdsteele@google.com (Matthew D. Steele)
#ifndef NET_INSTAWEB_HTMLPARSE_PUBLIC_HTML_NODE_H_
#define NET_INSTAWEB_HTMLPARSE_PUBLIC_HTML_NODE_H_
#include "base/basictypes.h"
#include "net/instaweb/htmlparse/public/html_parser_types.h"
#include <string>
#include "net/instaweb/util/public/string_util.h"
namespace net_instaweb {
// Base class for HtmlElement and HtmlLeafNode
class HtmlNode {
public:
virtual ~HtmlNode();
friend class HtmlParse;
HtmlElement* parent() const { return parent_; }
bool live() const { return live_; }
// Marks a node as dead. The queue's end iterator should be passed in,
// to remove references to stale iterators, and to force IsRewritable to
// return false.
void MarkAsDead(const HtmlEventListIterator& end);
protected:
// TODO(jmarantz): jmaessen suggests instantiating the html nodes
// without parents and computing them from context at the time they
// are instantiated from the lexer. This is a little more difficult
// when synthesizing new nodes, however. We assert sanity, however,
// when calling HtmlParse::ApplyFilter.
explicit HtmlNode(HtmlElement* parent) : parent_(parent), live_(true) {}
// Create new event object(s) representing this node, and insert them into
// the queue just before the given iterator; also, update this node object as
// necessary so that begin() and end() will return iterators pointing to
// the new event(s). The line number for each event should probably be -1.
virtual void SynthesizeEvents(const HtmlEventListIterator& iter,
HtmlEventList* queue) = 0;
virtual void InvalidateIterators(const HtmlEventListIterator& end) = 0;
// Return an iterator pointing to the first event associated with this node.
virtual HtmlEventListIterator begin() const = 0;
// Return an iterator pointing to the last event associated with this node.
virtual HtmlEventListIterator end() const = 0;
private:
friend class HtmlTestingPeer;
// Note: setting the parent doesn't change the DOM -- it just updates
// the pointer. This is intended to be called only from the DOM manipulation
// methods in HtmlParse.
void set_parent(HtmlElement* parent) { parent_ = parent; }
HtmlElement* parent_;
bool live_;
DISALLOW_COPY_AND_ASSIGN(HtmlNode);
};
// Base class for leaf nodes (like HtmlCharactersNode and HtmlCommentNode)
class HtmlLeafNode : public HtmlNode {
public:
virtual ~HtmlLeafNode();
friend class HtmlParse;
protected:
HtmlLeafNode(HtmlElement* parent, const HtmlEventListIterator& iter)
: HtmlNode(parent),
iter_(iter) {}
virtual HtmlEventListIterator begin() const { return iter_; }
virtual HtmlEventListIterator end() const { return iter_; }
void set_iter(const HtmlEventListIterator& iter) { iter_ = iter; }
virtual void InvalidateIterators(const HtmlEventListIterator& end);
private:
HtmlEventListIterator iter_;
DISALLOW_COPY_AND_ASSIGN(HtmlLeafNode);
};
// Leaf node representing a CDATA section
class HtmlCdataNode : public HtmlLeafNode {
public:
virtual ~HtmlCdataNode();
const std::string& contents() { return contents_; }
friend class HtmlParse;
protected:
virtual void SynthesizeEvents(const HtmlEventListIterator& iter,
HtmlEventList* queue);
private:
HtmlCdataNode(HtmlElement* parent,
const StringPiece& contents,
const HtmlEventListIterator& iter)
: HtmlLeafNode(parent, iter),
contents_(contents.data(), contents.size()) {}
const std::string contents_;
DISALLOW_COPY_AND_ASSIGN(HtmlCdataNode);
};
// Leaf node representing raw characters in HTML
class HtmlCharactersNode : public HtmlLeafNode {
public:
virtual ~HtmlCharactersNode();
const std::string& contents() { return contents_; }
void Append(const StringPiece& str) {
contents_.append(str.data(), str.size());
}
friend class HtmlParse;
protected:
virtual void SynthesizeEvents(const HtmlEventListIterator& iter,
HtmlEventList* queue);
private:
HtmlCharactersNode(HtmlElement* parent,
const StringPiece& contents,
const HtmlEventListIterator& iter)
: HtmlLeafNode(parent, iter),
contents_(contents.data(), contents.size()) {}
std::string contents_;
DISALLOW_COPY_AND_ASSIGN(HtmlCharactersNode);
};
// Leaf node representing an HTML comment
class HtmlCommentNode : public HtmlLeafNode {
public:
virtual ~HtmlCommentNode();
const std::string& contents() { return contents_; }
friend class HtmlParse;
protected:
virtual void SynthesizeEvents(const HtmlEventListIterator& iter,
HtmlEventList* queue);
private:
HtmlCommentNode(HtmlElement* parent,
const StringPiece& contents,
const HtmlEventListIterator& iter)
: HtmlLeafNode(parent, iter),
contents_(contents.data(), contents.size()) {}
const std::string contents_;
DISALLOW_COPY_AND_ASSIGN(HtmlCommentNode);
};
// Leaf node representing an HTML IE directive
class HtmlIEDirectiveNode : public HtmlLeafNode {
public:
virtual ~HtmlIEDirectiveNode();
const std::string& contents() { return contents_; }
friend class HtmlParse;
protected:
virtual void SynthesizeEvents(const HtmlEventListIterator& iter,
HtmlEventList* queue);
private:
HtmlIEDirectiveNode(HtmlElement* parent,
const StringPiece& contents,
const HtmlEventListIterator& iter)
: HtmlLeafNode(parent, iter),
contents_(contents.data(), contents.size()) {}
const std::string contents_;
DISALLOW_COPY_AND_ASSIGN(HtmlIEDirectiveNode);
};
// Leaf node representing an HTML directive
class HtmlDirectiveNode : public HtmlLeafNode {
public:
virtual ~HtmlDirectiveNode();
const std::string& contents() { return contents_; }
friend class HtmlParse;
protected:
virtual void SynthesizeEvents(const HtmlEventListIterator& iter,
HtmlEventList* queue);
private:
HtmlDirectiveNode(HtmlElement* parent,
const StringPiece& contents,
const HtmlEventListIterator& iter)
: HtmlLeafNode(parent, iter),
contents_(contents.data(), contents.size()) {}
const std::string contents_;
DISALLOW_COPY_AND_ASSIGN(HtmlDirectiveNode);
};
} // namespace net_instaweb
#endif // NET_INSTAWEB_HTMLPARSE_PUBLIC_HTML_NODE_H_