Page Speed Optimization Libraries  1.3.25.1
net/instaweb/rewriter/public/css_filter.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_REWRITER_PUBLIC_CSS_FILTER_H_
00020 #define NET_INSTAWEB_REWRITER_PUBLIC_CSS_FILTER_H_
00021 
00022 #include "net/instaweb/htmlparse/public/html_element.h"
00023 #include "net/instaweb/rewriter/public/css_hierarchy.h"
00024 #include "net/instaweb/rewriter/public/css_resource_slot.h"
00025 #include "net/instaweb/rewriter/public/css_url_encoder.h"
00026 #include "net/instaweb/rewriter/public/output_resource_kind.h"
00027 #include "net/instaweb/rewriter/public/resource.h"
00028 #include "net/instaweb/rewriter/public/server_context.h"
00029 #include "net/instaweb/rewriter/public/resource_slot.h"
00030 #include "net/instaweb/rewriter/public/rewrite_driver.h"
00031 #include "net/instaweb/rewriter/public/rewrite_filter.h"
00032 #include "net/instaweb/rewriter/public/rewrite_options.h"
00033 #include "net/instaweb/rewriter/public/single_rewrite_context.h"
00034 #include "net/instaweb/util/public/basictypes.h"
00035 #include "net/instaweb/util/public/google_url.h"
00036 #include "net/instaweb/util/public/scoped_ptr.h"
00037 #include "net/instaweb/util/public/string.h"
00038 #include "net/instaweb/util/public/string_util.h"
00039 
00040 namespace Css {
00041 
00042 class Stylesheet;
00043 
00044 }  
00045 
00046 namespace net_instaweb {
00047 
00048 class AssociationTransformer;
00049 class CssImageRewriter;
00050 class CacheExtender;
00051 class HtmlCharactersNode;
00052 class ImageCombineFilter;
00053 class ImageRewriteFilter;
00054 class MessageHandler;
00055 class OutputPartitions;
00056 class ResourceContext;
00057 class RewriteContext;
00058 class RewriteDomainTransformer;
00059 class Statistics;
00060 class UrlSegmentEncoder;
00061 class Variable;
00062 class Writer;
00063 
00074 class CssFilter : public RewriteFilter {
00075  public:
00076   class Context;
00077 
00078   CssFilter(RewriteDriver* driver,
00081             CacheExtender* cache_extender,
00082             ImageRewriteFilter* image_rewriter,
00083             ImageCombineFilter* image_combiner);
00084   virtual ~CssFilter();
00085 
00088   static void InitStats(Statistics* statistics);
00089 
00091   static void Initialize();
00092   static void Terminate();
00093 
00097   static void InitializeAtExitManager();
00098 
00099   virtual void StartDocumentImpl();
00100   virtual void StartElementImpl(HtmlElement* element);
00101   virtual void Characters(HtmlCharactersNode* characters);
00102   virtual void EndElementImpl(HtmlElement* element);
00103 
00104   virtual const char* Name() const { return "CssFilter"; }
00105   virtual const char* id() const { return RewriteOptions::kCssFilterId; }
00106   virtual int FilterCacheFormatVersion() const;
00107   virtual void EncodeUserAgentIntoResourceContext(
00108       ResourceContext* context) const;
00109 
00110   static const char kBlocksRewritten[];
00111   static const char kParseFailures[];
00112   static const char kFallbackRewrites[];
00113   static const char kFallbackFailures[];
00114   static const char kRewritesDropped[];
00115   static const char kTotalBytesSaved[];
00116   static const char kTotalOriginalBytes[];
00117   static const char kUses[];
00118   static const char kCharsetMismatch[];
00119   static const char kInvalidUrl[];
00120   static const char kLimitExceeded[];
00121   static const char kMinifyFailed[];
00122   static const char kRecursion[];
00123   static const char kComplexQueries[];
00124 
00125   RewriteContext* MakeNestedFlatteningContextInNewSlot(
00126       const ResourcePtr& resource, const GoogleString& location,
00127       CssFilter::Context* rewriter, RewriteContext* parent,
00128       CssHierarchy* hierarchy);
00129 
00130   virtual const RewriteOptions::Filter* RelatedFilters(int* num_filters) const;
00131   virtual const RewriteOptions::OptionEnum* RelatedOptions(
00132       int* num_options) const;
00133 
00134  protected:
00135   virtual RewriteContext* MakeRewriteContext();
00136   virtual const UrlSegmentEncoder* encoder() const;
00137   virtual RewriteContext* MakeNestedRewriteContext(
00138       RewriteContext* parent, const ResourceSlotPtr& slot);
00139 
00140  private:
00141   friend class Context;
00142   friend class CssFlattenImportsContext; 
00143   friend class CssHierarchy; 
00144 
00145   enum InlineCssKind {
00146     kInsideStyleTag,
00147     kAttributeWithoutUrls,
00148     kAttributeWithUrls
00149   };
00150 
00151   Context* MakeContext(RewriteDriver* driver,
00152                        RewriteContext* parent);
00153 
00155   void StartInlineRewrite(HtmlCharactersNode* text);
00156 
00159   void StartAttributeRewrite(HtmlElement* element,
00160                              HtmlElement::Attribute* style,
00161                              InlineCssKind inline_css_kind);
00162 
00165   void StartExternalRewrite(HtmlElement* link, HtmlElement::Attribute* src);
00166 
00167   ResourceSlot* MakeSlotForInlineCss(const StringPiece& content);
00168   CssFilter::Context* StartRewriting(const ResourceSlotPtr& slot);
00169 
00175   bool GetApplicableCharset(const HtmlElement* element,
00176                             GoogleString* charset) const;
00177 
00180   bool GetApplicableMedia(const HtmlElement* element,
00181                           StringVector* media) const;
00182 
00183   bool in_style_element_; 
00184 
00185   HtmlElement* style_element_; 
00186 
00188   GoogleString meta_tag_charset_;
00189 
00191   CacheExtender* cache_extender_;
00192   ImageRewriteFilter* image_rewrite_filter_;
00193   ImageCombineFilter* image_combiner_;
00194 
00198   Variable* num_blocks_rewritten_;
00200   Variable* num_parse_failures_;
00203   Variable* num_fallback_rewrites_;
00205   Variable* num_fallback_failures_;
00208   Variable* num_rewrites_dropped_;
00214   Variable* total_bytes_saved_;
00218   Variable* total_original_bytes_;
00221   Variable* num_uses_;
00223   Variable* num_flatten_imports_charset_mismatch_;
00225   Variable* num_flatten_imports_invalid_url_;
00227   Variable* num_flatten_imports_limit_exceeded_;
00229   Variable* num_flatten_imports_minify_failed_;
00231   Variable* num_flatten_imports_recursion_;
00233   Variable* num_flatten_imports_complex_queries_;
00234 
00235   CssUrlEncoder encoder_;
00236 
00237   DISALLOW_COPY_AND_ASSIGN(CssFilter);
00238 };
00239 
00241 class CssFilter::Context : public SingleRewriteContext {
00242  public:
00243   Context(CssFilter* filter, RewriteDriver* driver,
00244           RewriteContext* parent,
00245           CacheExtender* cache_extender,
00246           ImageRewriteFilter* image_rewriter,
00247           ImageCombineFilter* image_combiner,
00248           ResourceContext* context);
00249   virtual ~Context();
00250 
00252   void SetupInlineRewrite(HtmlElement* style_element, HtmlCharactersNode* text);
00253   void SetupAttributeRewrite(HtmlElement* element,
00254                              HtmlElement::Attribute* src,
00255                              InlineCssKind inline_css_kind);
00256   void SetupExternalRewrite(const GoogleUrl& base_gurl,
00257                             const GoogleUrl& trim_gurl);
00258 
00261   void RewriteCssFromNested(RewriteContext* parent, CssHierarchy* hierarchy);
00262 
00265   virtual bool AbsolutifyIfNeeded(const StringPiece& input_contents,
00266                                   Writer* writer, MessageHandler* handler);
00267 
00268   CssResourceSlotFactory* slot_factory() { return &slot_factory_; }
00269 
00270   CssHierarchy* mutable_hierarchy() { return &hierarchy_; }
00271 
00272  protected:
00273   virtual void Render();
00274   virtual void Harvest();
00275   virtual bool Partition(OutputPartitions* partitions,
00276                          OutputResourceVector* outputs);
00277   virtual void RewriteSingle(const ResourcePtr& input,
00278                              const OutputResourcePtr& output);
00279   virtual const char* id() const { return filter_->id(); }
00280   virtual OutputResourceKind kind() const { return kRewrittenResource; }
00281   virtual GoogleString CacheKeySuffix() const;
00282   virtual const UrlSegmentEncoder* encoder() const;
00283 
00285   virtual GoogleString UserAgentCacheKey(
00286       const ResourceContext* resource_context) const;
00287 
00288  private:
00289   bool RewriteCssText(const GoogleUrl& css_base_gurl,
00290                       const GoogleUrl& css_trim_gurl,
00291                       const StringPiece& in_text,
00292                       int64 in_text_size,
00293                       bool text_is_declarations,
00294                       MessageHandler* handler);
00295 
00297   void RewriteCssFromRoot(const StringPiece& in_text, int64 in_text_size,
00298                           bool has_unparseables, Css::Stylesheet* stylesheet);
00299 
00305   bool FallbackRewriteUrls(const StringPiece& in_text);
00306 
00309   bool SerializeCss(int64 in_text_size,
00310                     const Css::Stylesheet* stylesheet,
00311                     const GoogleUrl& css_base_gurl,
00312                     const GoogleUrl& css_trim_gurl,
00313                     bool previously_optimized,
00314                     bool stylesheet_is_declarations,
00315                     bool add_utf8_bom,
00316                     GoogleString* out_text,
00317                     MessageHandler* handler);
00318 
00322   bool IsInlineAttribute() const {
00323     return (rewrite_inline_attribute_ != NULL);
00324   }
00325 
00329   int64 ImageInlineMaxBytes() const {
00330     if (rewrite_inline_element_ != NULL) {
00332       return driver_->options()->ImageInlineMaxBytes();
00333     } else {
00335       return driver_->options()->CssImageInlineMaxBytes();
00336     }
00337   }
00338 
00339   CssFilter* filter_;
00340   RewriteDriver* driver_;
00341   scoped_ptr<CssImageRewriter> css_image_rewriter_;
00342   CssResourceSlotFactory slot_factory_;
00343   CssHierarchy hierarchy_;
00344   bool css_rewritten_;
00345   bool has_utf8_bom_;
00346 
00348   bool fallback_mode_;
00351   scoped_ptr<AssociationTransformer> fallback_transformer_;
00354   scoped_ptr<RewriteDomainTransformer> absolutifier_;
00355 
00359   HtmlElement* rewrite_inline_element_;
00360 
00362   HtmlCharactersNode* rewrite_inline_char_node_;
00363 
00367   HtmlElement::Attribute* rewrite_inline_attribute_;
00368 
00372   InlineCssKind rewrite_inline_css_kind_;
00373 
00375   int64 in_text_size_;
00376   GoogleUrl css_base_gurl_;
00377   GoogleUrl css_trim_gurl_;
00378   ResourcePtr input_resource_;
00379   OutputResourcePtr output_resource_;
00380 
00381   DISALLOW_COPY_AND_ASSIGN(Context);
00382 };
00383 
00384 }  
00385 
00386 #endif  ///< NET_INSTAWEB_REWRITER_PUBLIC_CSS_FILTER_H_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines