Page Speed Optimization Libraries  1.4.26.1
net/instaweb/htmlparse/public/html_element.h
Go to the documentation of this file.
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_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines