Page Speed Optimization Libraries  1.8.31.3
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_filter.h"
00031 #include "net/instaweb/rewriter/public/rewrite_options.h"
00032 #include "net/instaweb/rewriter/public/single_rewrite_context.h"
00033 #include "net/instaweb/util/public/basictypes.h"
00034 #include "net/instaweb/util/public/google_url.h"
00035 #include "net/instaweb/util/public/scoped_ptr.h"
00036 #include "net/instaweb/util/public/string.h"
00037 #include "net/instaweb/util/public/string_util.h"
00038 
00039 namespace Css {
00040 
00041 class Stylesheet;
00042 
00043 }  
00044 
00045 namespace net_instaweb {
00046 
00047 class AssociationTransformer;
00048 class AsyncFetch;
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 RewriteDriver;
00059 class RewriteDomainTransformer;
00060 class Statistics;
00061 class UpDownCounter;
00062 class UrlSegmentEncoder;
00063 class Variable;
00064 
00075 class CssFilter : public RewriteFilter {
00076  public:
00077   class Context;
00078 
00079   CssFilter(RewriteDriver* driver,
00082             CacheExtender* cache_extender,
00083             ImageRewriteFilter* image_rewriter,
00084             ImageCombineFilter* image_combiner);
00085   virtual ~CssFilter();
00086 
00089   static void InitStats(Statistics* statistics);
00090 
00092   static void Initialize();
00093   static void Terminate();
00094 
00096   static void AddRelatedOptions(StringPieceVector* target);
00097 
00101   static void InitializeAtExitManager();
00102 
00103   virtual void StartDocumentImpl();
00104   virtual void StartElementImpl(HtmlElement* element);
00105   virtual void Characters(HtmlCharactersNode* characters);
00106   virtual void EndElementImpl(HtmlElement* element);
00107 
00108   virtual const char* Name() const { return "CssFilter"; }
00109   virtual const char* id() const { return RewriteOptions::kCssFilterId; }
00110   virtual void EncodeUserAgentIntoResourceContext(
00111       ResourceContext* context) const;
00112 
00113   static const char kBlocksRewritten[];
00114   static const char kParseFailures[];
00115   static const char kFallbackRewrites[];
00116   static const char kFallbackFailures[];
00117   static const char kRewritesDropped[];
00118   static const char kTotalBytesSaved[];
00119   static const char kTotalOriginalBytes[];
00120   static const char kUses[];
00121   static const char kCharsetMismatch[];
00122   static const char kInvalidUrl[];
00123   static const char kLimitExceeded[];
00124   static const char kMinifyFailed[];
00125   static const char kRecursion[];
00126   static const char kComplexQueries[];
00127 
00128   RewriteContext* MakeNestedFlatteningContextInNewSlot(
00129       const ResourcePtr& resource, const GoogleString& location,
00130       CssFilter::Context* rewriter, RewriteContext* parent,
00131       CssHierarchy* hierarchy);
00132 
00133   virtual const RewriteOptions::Filter* RelatedFilters(int* num_filters) const {
00134     *num_filters = merged_filters_size_;
00135     return merged_filters_;
00136   }
00137   virtual const StringPieceVector* RelatedOptions() const {
00138     return related_options_;
00139   }
00140 
00141  protected:
00142   virtual RewriteContext* MakeRewriteContext();
00143   virtual const UrlSegmentEncoder* encoder() const;
00144   virtual RewriteContext* MakeNestedRewriteContext(
00145       RewriteContext* parent, const ResourceSlotPtr& slot);
00146 
00147  private:
00148   friend class Context;
00149   friend class CssFlattenImportsContext; 
00150   friend class CssHierarchy; 
00151 
00152   enum InlineCssKind {
00153     kInsideStyleTag,
00154     kAttributeWithoutUrls,
00155     kAttributeWithUrls
00156   };
00157 
00158   Context* MakeContext(RewriteDriver* driver,
00159                        RewriteContext* parent);
00160 
00162   void StartInlineRewrite(HtmlCharactersNode* text);
00163 
00166   void StartAttributeRewrite(HtmlElement* element,
00167                              HtmlElement::Attribute* style,
00168                              InlineCssKind inline_css_kind);
00169 
00172   void StartExternalRewrite(HtmlElement* link, HtmlElement::Attribute* src);
00173 
00174   ResourceSlot* MakeSlotForInlineCss(const StringPiece& content);
00175   CssFilter::Context* StartRewriting(const ResourceSlotPtr& slot);
00176 
00182   bool GetApplicableCharset(const HtmlElement* element,
00183                             GoogleString* charset,
00184                             GoogleString* failure_reason) const;
00185 
00188   bool GetApplicableMedia(const HtmlElement* element,
00189                           StringVector* media) const;
00190 
00191   bool in_style_element_; 
00192 
00193   HtmlElement* style_element_; 
00194 
00196   GoogleString meta_tag_charset_;
00197 
00199   CacheExtender* cache_extender_;
00200   ImageRewriteFilter* image_rewrite_filter_;
00201   ImageCombineFilter* image_combiner_;
00202 
00206   Variable* num_blocks_rewritten_;
00208   Variable* num_parse_failures_;
00211   Variable* num_fallback_rewrites_;
00213   Variable* num_fallback_failures_;
00216   Variable* num_rewrites_dropped_;
00222   UpDownCounter* total_bytes_saved_;
00226   Variable* total_original_bytes_;
00229   Variable* num_uses_;
00231   Variable* num_flatten_imports_charset_mismatch_;
00233   Variable* num_flatten_imports_invalid_url_;
00235   Variable* num_flatten_imports_limit_exceeded_;
00237   Variable* num_flatten_imports_minify_failed_;
00239   Variable* num_flatten_imports_recursion_;
00241   Variable* num_flatten_imports_complex_queries_;
00242 
00243   CssUrlEncoder encoder_;
00244 
00246   static const RewriteOptions::Filter* merged_filters_;
00247   static int merged_filters_size_;
00248 
00250   static StringPieceVector* related_options_;
00251 
00252   DISALLOW_COPY_AND_ASSIGN(CssFilter);
00253 };
00254 
00256 class CssFilter::Context : public SingleRewriteContext {
00257  public:
00258   Context(CssFilter* filter, RewriteDriver* driver,
00259           RewriteContext* parent,
00260           CacheExtender* cache_extender,
00261           ImageRewriteFilter* image_rewriter,
00262           ImageCombineFilter* image_combiner,
00263           ResourceContext* context);
00264   virtual ~Context();
00265 
00267   void SetupInlineRewrite(HtmlElement* style_element, HtmlCharactersNode* text);
00268   void SetupAttributeRewrite(HtmlElement* element,
00269                              HtmlElement::Attribute* src,
00270                              InlineCssKind inline_css_kind);
00271   void SetupExternalRewrite(HtmlElement* element,
00272                             const GoogleUrl& base_gurl,
00273                             const GoogleUrl& trim_gurl);
00274 
00277   void RewriteCssFromNested(RewriteContext* parent, CssHierarchy* hierarchy);
00278 
00281   virtual bool SendFallbackResponse(StringPiece output_url_base,
00282                                     StringPiece input_contents,
00283                                     AsyncFetch* async_fetch,
00284                                     MessageHandler* handler);
00285 
00286   CssResourceSlotFactory* slot_factory() { return &slot_factory_; }
00287 
00288   CssHierarchy* mutable_hierarchy() { return &hierarchy_; }
00289 
00290  protected:
00291   virtual void Render();
00292   virtual void Harvest();
00293   virtual bool Partition(OutputPartitions* partitions,
00294                          OutputResourceVector* outputs);
00295   virtual void RewriteSingle(const ResourcePtr& input,
00296                              const OutputResourcePtr& output);
00297   virtual const char* id() const { return filter_->id(); }
00298   virtual OutputResourceKind kind() const { return kRewrittenResource; }
00299   virtual GoogleString CacheKeySuffix() const;
00300   virtual const UrlSegmentEncoder* encoder() const;
00301 
00303   virtual GoogleString UserAgentCacheKey(
00304       const ResourceContext* resource_context) const;
00305 
00306  private:
00307   void GetCssBaseUrlToUse(const ResourcePtr& input_resource,
00308                           GoogleUrl* css_base_gurl_to_use);
00309 
00310   void GetCssTrimUrlToUse(const ResourcePtr& input_resource,
00311                           const StringPiece& output_url_base,
00312                           GoogleUrl* css_base_gurl_to_use);
00313 
00314   void GetCssTrimUrlToUse(const ResourcePtr& input_resource,
00315                           const OutputResourcePtr& output_resource,
00316                           GoogleUrl* css_base_gurl_to_use);
00317 
00318   bool RewriteCssText(const GoogleUrl& css_base_gurl,
00319                       const GoogleUrl& css_trim_gurl,
00320                       const StringPiece& in_text,
00321                       int64 in_text_size,
00322                       bool text_is_declarations,
00323                       MessageHandler* handler);
00324 
00326   void RewriteCssFromRoot(const GoogleUrl& css_base_gurl,
00327                           const GoogleUrl& css_trim_gurl,
00328                           const StringPiece& in_text, int64 in_text_size,
00329                           bool has_unparseables, Css::Stylesheet* stylesheet);
00330 
00336   bool FallbackRewriteUrls(const GoogleUrl& css_base_gurl,
00337                            const GoogleUrl& css_trim_gurl,
00338                            const StringPiece& in_text);
00339 
00342   bool SerializeCss(int64 in_text_size,
00343                     const Css::Stylesheet* stylesheet,
00344                     const GoogleUrl& css_base_gurl,
00345                     const GoogleUrl& css_trim_gurl,
00346                     bool previously_optimized,
00347                     bool stylesheet_is_declarations,
00348                     bool add_utf8_bom,
00349                     GoogleString* out_text,
00350                     MessageHandler* handler);
00351 
00355   bool IsInlineAttribute() const {
00356     return (rewrite_inline_attribute_ != NULL);
00357   }
00358 
00362   int64 ImageInlineMaxBytes() const;
00363 
00364   CssFilter* filter_;
00365   scoped_ptr<CssImageRewriter> css_image_rewriter_;
00366   CssResourceSlotFactory slot_factory_;
00367   CssHierarchy hierarchy_;
00368   bool css_rewritten_;
00369   bool has_utf8_bom_;
00370 
00372   bool fallback_mode_;
00375   scoped_ptr<AssociationTransformer> fallback_transformer_;
00378   scoped_ptr<RewriteDomainTransformer> absolutifier_;
00379 
00382   HtmlElement* rewrite_element_;
00383 
00387   HtmlElement* rewrite_inline_element_;
00388 
00390   HtmlCharactersNode* rewrite_inline_char_node_;
00391 
00395   HtmlElement::Attribute* rewrite_inline_attribute_;
00396 
00400   InlineCssKind rewrite_inline_css_kind_;
00401 
00403   int64 in_text_size_;
00404   GoogleUrl initial_css_base_gurl_;
00405   GoogleUrl initial_css_trim_gurl_;
00406   scoped_ptr<GoogleUrl> base_gurl_for_fallback_;
00407   scoped_ptr<GoogleUrl> trim_gurl_for_fallback_;
00408   ResourcePtr input_resource_;
00409   OutputResourcePtr output_resource_;
00410 
00411   DISALLOW_COPY_AND_ASSIGN(Context);
00412 };
00413 
00414 }  
00415 
00416 #endif  ///< NET_INSTAWEB_REWRITER_PUBLIC_CSS_FILTER_H_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines