Page Speed Optimization Libraries
1.4.26.1
|
00001 /* 00002 * Copyright 2010 Google Inc. 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http:///www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00018 00019 #ifndef NET_INSTAWEB_HTMLPARSE_PUBLIC_HTML_ELEMENT_H_ 00020 #define NET_INSTAWEB_HTMLPARSE_PUBLIC_HTML_ELEMENT_H_ 00021 00022 #include "net/instaweb/htmlparse/public/html_name.h" 00023 #include "net/instaweb/htmlparse/public/html_node.h" 00024 #include "net/instaweb/util/public/basictypes.h" 00025 #include "net/instaweb/util/public/inline_slist.h" 00026 #include "net/instaweb/util/public/scoped_ptr.h" 00027 #include "net/instaweb/util/public/string.h" 00028 #include "net/instaweb/util/public/string_util.h" 00029 00030 namespace net_instaweb { 00031 00032 class HtmlElement : public HtmlNode { 00033 public: 00040 enum CloseStyle { 00041 AUTO_CLOSE, 00042 IMPLICIT_CLOSE, 00043 EXPLICIT_CLOSE, 00044 BRIEF_CLOSE, 00045 UNCLOSED 00046 }; 00047 00049 enum QuoteStyle { 00050 NO_QUOTE, 00051 SINGLE_QUOTE, 00052 DOUBLE_QUOTE 00053 }; 00054 00055 class Attribute : public InlineSListElement<Attribute> { 00056 public: 00060 00064 00068 const char* name_str() const { return name_.c_str(); } 00069 00073 HtmlName::Keyword keyword() const { return name_.keyword(); } 00074 00075 HtmlName name() const { return name_; } 00076 void set_name(const HtmlName& name) { name_ = name; } 00077 00080 const char* escaped_value() const { return escaped_value_.get(); } 00081 00107 const char* DecodedValueOrNull() const { 00108 if (!decoded_value_computed_) { 00109 ComputeDecodedValue(); 00110 } 00111 return decoded_value_.get(); 00112 } 00113 00114 void set_decoding_error(bool x) { decoding_error_ = x; } 00115 bool decoding_error() const { 00116 if (!decoded_value_computed_) { 00117 ComputeDecodedValue(); 00118 } 00119 return decoding_error_; 00120 } 00121 00124 QuoteStyle quote_style() const { return quote_style_; } 00125 00127 const char* quote_str() const; 00128 00142 00147 void SetValue(const StringPiece& value); 00148 00152 void SetEscapedValue(const StringPiece& value); 00153 00154 void set_quote_style(QuoteStyle new_quote_style) { 00155 quote_style_ = new_quote_style; 00156 } 00157 00158 friend class HtmlElement; 00159 00160 private: 00161 void ComputeDecodedValue() const; 00162 00164 Attribute(const HtmlName& name, const StringPiece& escaped_value, 00165 QuoteStyle quote_style); 00166 00167 static inline void CopyValue(const StringPiece& src, 00168 scoped_array<char>* dst); 00169 00170 HtmlName name_; 00171 QuoteStyle quote_style_ : 8; 00172 mutable bool decoding_error_; 00173 mutable bool decoded_value_computed_; 00174 00183 scoped_array<char> escaped_value_; 00184 00201 mutable scoped_array<char> decoded_value_; 00202 00203 DISALLOW_COPY_AND_ASSIGN(Attribute); 00204 }; 00205 00206 typedef InlineSList<Attribute> AttributeList; 00207 typedef InlineSList<Attribute>::Iterator AttributeIterator; 00208 typedef InlineSList<Attribute>::ConstIterator AttributeConstIterator; 00209 00210 virtual ~HtmlElement(); 00211 00212 virtual bool live() const { return (data_.get() != NULL) && data_->live_; } 00213 virtual void MarkAsDead(const HtmlEventListIterator& end); 00214 00217 void AddAttribute(const Attribute& attr); 00218 00228 void AddAttribute(const HtmlName& name, 00229 const StringPiece& decoded_value, 00230 QuoteStyle quote_style); 00232 void AddEscapedAttribute(const HtmlName& name, 00233 const StringPiece& escaped_value, 00234 QuoteStyle quote_style); 00235 00238 bool DeleteAttribute(HtmlName::Keyword keyword); 00239 00243 const Attribute* FindAttribute(HtmlName::Keyword keyword) const; 00244 Attribute* FindAttribute(HtmlName::Keyword keyword) { 00245 const HtmlElement* const_this = this; 00246 const Attribute* result = const_this->FindAttribute(keyword); 00247 return const_cast<Attribute*>(result); 00248 } 00249 00259 const char* AttributeValue(HtmlName::Keyword name) const { 00260 const Attribute* attribute = FindAttribute(name); 00261 if (attribute != NULL) { 00262 return attribute->DecodedValueOrNull(); 00263 } 00264 return NULL; 00265 } 00266 00275 const char* EscapedAttributeValue(HtmlName::Keyword name) const { 00276 const Attribute* attribute = FindAttribute(name); 00277 if (attribute != NULL) { 00278 return attribute->escaped_value(); 00279 } 00280 return NULL; 00281 } 00282 00286 const char* name_str() const { return data_->name_.c_str(); } 00287 00291 HtmlName::Keyword keyword() const { return data_->name_.keyword(); } 00292 00293 const HtmlName& name() const { return data_->name_; } 00294 00298 void set_name(const HtmlName& new_tag) { data_->name_ = new_tag; } 00299 00300 const AttributeList& attributes() const { return data_->attributes_; } 00301 AttributeList* mutable_attributes() { return &data_->attributes_; } 00302 00303 friend class HtmlParse; 00304 friend class HtmlLexer; 00305 00306 CloseStyle close_style() const { return data_->close_style_; } 00307 void set_close_style(CloseStyle style) { data_->close_style_ = style; } 00308 00311 void ToString(GoogleString* buf) const; 00312 void DebugPrint() const; 00313 00314 int begin_line_number() const { return data_->begin_line_number_; } 00315 int end_line_number() const { return data_->end_line_number_; } 00316 00317 protected: 00318 virtual void SynthesizeEvents(const HtmlEventListIterator& iter, 00319 HtmlEventList* queue); 00320 00321 virtual HtmlEventListIterator begin() const { return data_->begin_; } 00322 virtual HtmlEventListIterator end() const { return data_->end_; } 00323 00324 private: 00327 struct Data { 00328 Data(const HtmlName& name, 00329 const HtmlEventListIterator& begin, 00330 const HtmlEventListIterator& end); 00331 ~Data(); 00332 00344 unsigned begin_line_number_ : 24; 00345 unsigned live_ : 8; 00346 unsigned end_line_number_ : 24; 00347 CloseStyle close_style_ : 8; 00348 00349 HtmlName name_; 00350 AttributeList attributes_; 00351 HtmlEventListIterator begin_; 00352 HtmlEventListIterator end_; 00353 }; 00354 00358 void set_begin(const HtmlEventListIterator& begin) { data_->begin_ = begin; } 00359 void set_end(const HtmlEventListIterator& end) { data_->end_ = end; } 00360 00361 void set_begin_line_number(int line) { data_->begin_line_number_ = line; } 00362 void set_end_line_number(int line) { data_->end_line_number_ = line; } 00363 00365 HtmlElement(HtmlElement* parent, const HtmlName& name, 00366 const HtmlEventListIterator& begin, 00367 const HtmlEventListIterator& end); 00368 00374 void FreeData() { data_.reset(NULL); } 00375 00376 scoped_ptr<Data> data_; 00377 00378 DISALLOW_COPY_AND_ASSIGN(HtmlElement); 00379 }; 00380 00381 } 00382 00383 #endif ///< NET_INSTAWEB_HTMLPARSE_PUBLIC_HTML_ELEMENT_H_