Page Speed Optimization Libraries
1.3.25.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_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_