Page Speed Optimization Libraries  1.5.27.2
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 
00042 class HtmlElement : public HtmlNode {
00043  public:
00050   enum CloseStyle {
00051     AUTO_CLOSE,      
00052     IMPLICIT_CLOSE,  
00053     EXPLICIT_CLOSE,  
00054     BRIEF_CLOSE,     
00055     UNCLOSED         
00056   };
00057 
00059   enum QuoteStyle {
00060     NO_QUOTE,
00061     SINGLE_QUOTE,
00062     DOUBLE_QUOTE
00063   };
00064 
00065   class Attribute : public InlineSListElement<Attribute> {
00066    public:
00070 
00074 
00078     const char* name_str() const { return name_.c_str(); }
00079 
00083     HtmlName::Keyword keyword() const { return name_.keyword(); }
00084 
00085     HtmlName name() const { return name_; }
00086     void set_name(const HtmlName& name) { name_ = name; }
00087 
00090     const char* escaped_value() const { return escaped_value_.get(); }
00091 
00117     const char* DecodedValueOrNull() const {
00118       if (!decoded_value_computed_) {
00119         ComputeDecodedValue();
00120       }
00121       return decoded_value_.get();
00122     }
00123 
00124     void set_decoding_error(bool x) { decoding_error_ = x; }
00125     bool decoding_error() const {
00126       if (!decoded_value_computed_) {
00127         ComputeDecodedValue();
00128       }
00129       return decoding_error_;
00130     }
00131 
00134     QuoteStyle quote_style() const { return quote_style_; }
00135 
00137     const char* quote_str() const;
00138 
00152 
00157     void SetValue(const StringPiece& value);
00158 
00162     void SetEscapedValue(const StringPiece& value);
00163 
00164     void set_quote_style(QuoteStyle new_quote_style) {
00165       quote_style_ = new_quote_style;
00166     }
00167 
00168     friend class HtmlElement;
00169 
00170    private:
00171     void ComputeDecodedValue() const;
00172 
00174     Attribute(const HtmlName& name, const StringPiece& escaped_value,
00175               QuoteStyle quote_style);
00176 
00177     static inline void CopyValue(const StringPiece& src,
00178                                  scoped_array<char>* dst);
00179 
00180     HtmlName name_;
00181     QuoteStyle quote_style_ : 8;
00182     mutable bool decoding_error_;
00183     mutable bool decoded_value_computed_;
00184 
00193     scoped_array<char> escaped_value_;
00194 
00211     mutable scoped_array<char> decoded_value_;
00212 
00213     DISALLOW_COPY_AND_ASSIGN(Attribute);
00214   };
00215 
00216   typedef InlineSList<Attribute> AttributeList;
00217   typedef InlineSList<Attribute>::Iterator AttributeIterator;
00218   typedef InlineSList<Attribute>::ConstIterator AttributeConstIterator;
00219 
00220   virtual ~HtmlElement();
00221 
00228   virtual bool live() const { return (data_.get() != NULL) && data_->live_; }
00229 
00230   virtual void MarkAsDead(const HtmlEventListIterator& end);
00231 
00234   void AddAttribute(const Attribute& attr);
00235 
00245   void AddAttribute(const HtmlName& name,
00246                     const StringPiece& decoded_value,
00247                     QuoteStyle quote_style);
00249   void AddEscapedAttribute(const HtmlName& name,
00250                            const StringPiece& escaped_value,
00251                            QuoteStyle quote_style);
00252 
00255   bool DeleteAttribute(HtmlName::Keyword keyword);
00256 
00260   const Attribute* FindAttribute(HtmlName::Keyword keyword) const;
00261   Attribute* FindAttribute(HtmlName::Keyword keyword) {
00262     const HtmlElement* const_this = this;
00263     const Attribute* result = const_this->FindAttribute(keyword);
00264     return const_cast<Attribute*>(result);
00265   }
00266 
00276   const char* AttributeValue(HtmlName::Keyword name) const {
00277     const Attribute* attribute = FindAttribute(name);
00278     if (attribute != NULL) {
00279       return attribute->DecodedValueOrNull();
00280     }
00281     return NULL;
00282   }
00283 
00292   const char* EscapedAttributeValue(HtmlName::Keyword name) const {
00293     const Attribute* attribute = FindAttribute(name);
00294     if (attribute != NULL) {
00295       return attribute->escaped_value();
00296     }
00297     return NULL;
00298   }
00299 
00303   const char* name_str() const { return data_->name_.c_str(); }
00304 
00308   HtmlName::Keyword keyword() const { return data_->name_.keyword(); }
00309 
00310   const HtmlName& name() const { return data_->name_; }
00311 
00315   void set_name(const HtmlName& new_tag) { data_->name_ = new_tag; }
00316 
00317   const AttributeList& attributes() const { return data_->attributes_; }
00318   AttributeList* mutable_attributes() { return &data_->attributes_; }
00319 
00320   friend class HtmlParse;
00321   friend class HtmlLexer;
00322 
00323   CloseStyle close_style() const { return data_->close_style_; }
00324   void set_close_style(CloseStyle style) { data_->close_style_ = style; }
00325 
00328   void ToString(GoogleString* buf) const;
00329   void DebugPrint() const;
00330 
00331   int begin_line_number() const { return data_->begin_line_number_; }
00332   int end_line_number() const { return data_->end_line_number_; }
00333 
00334  protected:
00335   virtual void SynthesizeEvents(const HtmlEventListIterator& iter,
00336                                 HtmlEventList* queue);
00337 
00338   virtual HtmlEventListIterator begin() const { return data_->begin_; }
00339   virtual HtmlEventListIterator end() const { return data_->end_; }
00340 
00341  private:
00344   struct Data {
00345     Data(const HtmlName& name,
00346          const HtmlEventListIterator& begin,
00347          const HtmlEventListIterator& end);
00348     ~Data();
00349 
00361     unsigned begin_line_number_ : 24;
00362     unsigned live_ : 8;
00363     unsigned end_line_number_ : 24;
00364     CloseStyle close_style_ : 8;
00365 
00366     HtmlName name_;
00367     AttributeList attributes_;
00368     HtmlEventListIterator begin_;
00369     HtmlEventListIterator end_;
00370   };
00371 
00375   void set_begin(const HtmlEventListIterator& begin) { data_->begin_ = begin; }
00376   void set_end(const HtmlEventListIterator& end) { data_->end_ = end; }
00377 
00378   void set_begin_line_number(int line) { data_->begin_line_number_ = line; }
00379   void set_end_line_number(int line) { data_->end_line_number_ = line; }
00380 
00382   HtmlElement(HtmlElement* parent, const HtmlName& name,
00383               const HtmlEventListIterator& begin,
00384               const HtmlEventListIterator& end);
00385 
00391   void FreeData() { data_.reset(NULL); }
00392 
00393   scoped_ptr<Data> data_;
00394 
00395   DISALLOW_COPY_AND_ASSIGN(HtmlElement);
00396 };
00397 
00398 }  
00399 
00400 #endif  ///< NET_INSTAWEB_HTMLPARSE_PUBLIC_HTML_ELEMENT_H_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines