00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00018
00019 #ifndef NET_INSTAWEB_HTMLPARSE_PUBLIC_HTML_NODE_H_
00020 #define NET_INSTAWEB_HTMLPARSE_PUBLIC_HTML_NODE_H_
00021
00022 #include <cstddef>
00023
00024 #include "base/logging.h"
00025 #include "base/scoped_ptr.h"
00026 #include "net/instaweb/util/public/basictypes.h"
00027 #include "net/instaweb/htmlparse/public/html_parser_types.h"
00028 #include "net/instaweb/util/public/arena.h"
00029 #include "net/instaweb/util/public/string.h"
00030 #include "net/instaweb/util/public/string_util.h"
00031
00032 namespace net_instaweb {
00033
00034 class HtmlElement;
00035
00037 class HtmlNode {
00038 public:
00039 virtual ~HtmlNode();
00040 friend class HtmlParse;
00041
00042 HtmlElement* parent() const { return parent_; }
00043 virtual bool live() const = 0;
00044
00048 virtual void MarkAsDead(const HtmlEventListIterator& end) = 0;
00049
00050 void* operator new(size_t size, Arena<HtmlNode>* arena) {
00051 return arena->Allocate(size);
00052 }
00053
00054 void operator delete(void* ptr, Arena<HtmlNode>* arena) {
00055 LOG(FATAL) << "HtmlNode must not be deleted directly.";
00056 }
00057
00058 protected:
00064 explicit HtmlNode(HtmlElement* parent) : parent_(parent) {}
00065
00070 virtual void SynthesizeEvents(const HtmlEventListIterator& iter,
00071 HtmlEventList* queue) = 0;
00072
00074 virtual HtmlEventListIterator begin() const = 0;
00076 virtual HtmlEventListIterator end() const = 0;
00077
00079 void operator delete(void* ptr) {
00080 LOG(FATAL) << "HtmlNode must not be deleted directly.";
00081 }
00082
00083 private:
00084 friend class HtmlLexer;
00085 friend class HtmlTestingPeer;
00086
00090 void set_parent(HtmlElement* parent) { parent_ = parent; }
00091
00092 HtmlElement* parent_;
00093 DISALLOW_COPY_AND_ASSIGN(HtmlNode);
00094 };
00095
00096 class HtmlLeafNode : public HtmlNode {
00097 public:
00098 virtual ~HtmlLeafNode();
00099 virtual bool live() const { return (data_.get() != NULL) && data_->is_live_; }
00100 virtual void MarkAsDead(const HtmlEventListIterator& end);
00101
00102 const GoogleString& contents() const { return data_->contents_; }
00103 virtual HtmlEventListIterator begin() const {
00104 return data_->iter_;
00105 }
00106 virtual HtmlEventListIterator end() const {
00107 return data_->iter_;
00108 }
00109 void set_iter(const HtmlEventListIterator& iter) {
00110 data_->iter_ = iter;
00111 }
00112
00113 void FreeData() { data_.reset(NULL); }
00114
00115 protected:
00116 HtmlLeafNode(HtmlElement* parent, const HtmlEventListIterator& iter,
00117 const StringPiece& contents);
00118
00121 GoogleString* mutable_contents() { return &data_->contents_; }
00122
00123 private:
00124 struct Data {
00125 Data(const HtmlEventListIterator& iter, const StringPiece& contents)
00126 : contents_(contents.data(), contents.size()),
00127 is_live_(true),
00128 iter_(iter) {
00129 }
00130 GoogleString contents_;
00131 bool is_live_;
00132 HtmlEventListIterator iter_;
00133 };
00134
00135 scoped_ptr<Data> data_;
00136 };
00137
00139 class HtmlCdataNode : public HtmlLeafNode {
00140 public:
00141 virtual ~HtmlCdataNode();
00142 friend class HtmlParse;
00143
00144 protected:
00145 virtual void SynthesizeEvents(const HtmlEventListIterator& iter,
00146 HtmlEventList* queue);
00147
00148 private:
00149 HtmlCdataNode(HtmlElement* parent,
00150 const StringPiece& contents,
00151 const HtmlEventListIterator& iter)
00152 : HtmlLeafNode(parent, iter, contents) {
00153 }
00154
00155 DISALLOW_COPY_AND_ASSIGN(HtmlCdataNode);
00156 };
00157
00159 class HtmlCharactersNode : public HtmlLeafNode {
00160 public:
00161 virtual ~HtmlCharactersNode();
00162 void Append(const StringPiece& str) {
00163 mutable_contents()->append(str.data(), str.size());
00164 }
00165 friend class HtmlParse;
00166
00168 using HtmlLeafNode::mutable_contents;
00169
00170 protected:
00171 virtual void SynthesizeEvents(const HtmlEventListIterator& iter,
00172 HtmlEventList* queue);
00173
00174 private:
00175 HtmlCharactersNode(HtmlElement* parent,
00176 const StringPiece& contents,
00177 const HtmlEventListIterator& iter)
00178 : HtmlLeafNode(parent, iter, contents) {
00179 }
00180
00181 DISALLOW_COPY_AND_ASSIGN(HtmlCharactersNode);
00182 };
00183
00185 class HtmlCommentNode : public HtmlLeafNode {
00186 public:
00187 virtual ~HtmlCommentNode();
00188 friend class HtmlParse;
00189
00190 protected:
00191 virtual void SynthesizeEvents(const HtmlEventListIterator& iter,
00192 HtmlEventList* queue);
00193
00194 private:
00195 HtmlCommentNode(HtmlElement* parent,
00196 const StringPiece& contents,
00197 const HtmlEventListIterator& iter)
00198 : HtmlLeafNode(parent, iter, contents) {
00199 }
00200
00201 DISALLOW_COPY_AND_ASSIGN(HtmlCommentNode);
00202 };
00203
00205 class HtmlIEDirectiveNode : public HtmlLeafNode {
00206 public:
00207 virtual ~HtmlIEDirectiveNode();
00208 friend class HtmlParse;
00209
00210 protected:
00211 virtual void SynthesizeEvents(const HtmlEventListIterator& iter,
00212 HtmlEventList* queue);
00213
00214 private:
00215 HtmlIEDirectiveNode(HtmlElement* parent,
00216 const StringPiece& contents,
00217 const HtmlEventListIterator& iter)
00218 : HtmlLeafNode(parent, iter, contents) {
00219 }
00220
00221 DISALLOW_COPY_AND_ASSIGN(HtmlIEDirectiveNode);
00222 };
00223
00225 class HtmlDirectiveNode : public HtmlLeafNode {
00226 public:
00227 virtual ~HtmlDirectiveNode();
00228 friend class HtmlParse;
00229
00230 protected:
00231 virtual void SynthesizeEvents(const HtmlEventListIterator& iter,
00232 HtmlEventList* queue);
00233
00234 private:
00235 HtmlDirectiveNode(HtmlElement* parent,
00236 const StringPiece& contents,
00237 const HtmlEventListIterator& iter)
00238 : HtmlLeafNode(parent, iter, contents) {
00239 }
00240
00241 DISALLOW_COPY_AND_ASSIGN(HtmlDirectiveNode);
00242 };
00243
00244 }
00245
00246 #endif ///< NET_INSTAWEB_HTMLPARSE_PUBLIC_HTML_NODE_H_