Page Speed Optimization Libraries
1.2.24.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 00108 static const char kBlocksRewritten[]; 00109 static const char kParseFailures[]; 00110 static const char kFallbackRewrites[]; 00111 static const char kFallbackFailures[]; 00112 static const char kRewritesDropped[]; 00113 static const char kTotalBytesSaved[]; 00114 static const char kTotalOriginalBytes[]; 00115 static const char kUses[]; 00116 static const char kCharsetMismatch[]; 00117 static const char kInvalidUrl[]; 00118 static const char kLimitExceeded[]; 00119 static const char kMinifyFailed[]; 00120 static const char kRecursion[]; 00121 static const char kComplexQueries[]; 00122 00123 RewriteContext* MakeNestedFlatteningContextInNewSlot( 00124 const ResourcePtr& resource, const GoogleString& location, 00125 CssFilter::Context* rewriter, RewriteContext* parent, 00126 CssHierarchy* hierarchy); 00127 00128 protected: 00129 virtual RewriteContext* MakeRewriteContext(); 00130 virtual const UrlSegmentEncoder* encoder() const; 00131 virtual RewriteContext* MakeNestedRewriteContext( 00132 RewriteContext* parent, const ResourceSlotPtr& slot); 00133 00134 private: 00135 friend class Context; 00136 friend class CssFlattenImportsContext; 00137 friend class CssHierarchy; 00138 00139 enum InlineCssKind { 00140 kInsideStyleTag, 00141 kAttributeWithoutUrls, 00142 kAttributeWithUrls 00143 }; 00144 00145 Context* MakeContext(RewriteDriver* driver, 00146 RewriteContext* parent); 00147 00149 void StartInlineRewrite(HtmlCharactersNode* text); 00150 00153 void StartAttributeRewrite(HtmlElement* element, 00154 HtmlElement::Attribute* style, 00155 InlineCssKind inline_css_kind); 00156 00159 void StartExternalRewrite(HtmlElement* link, HtmlElement::Attribute* src); 00160 00161 ResourceSlot* MakeSlotForInlineCss(const StringPiece& content); 00162 CssFilter::Context* StartRewriting(const ResourceSlotPtr& slot); 00163 00169 bool GetApplicableCharset(const HtmlElement* element, 00170 GoogleString* charset) const; 00171 00174 bool GetApplicableMedia(const HtmlElement* element, 00175 StringVector* media) const; 00176 00177 bool in_style_element_; 00178 00179 HtmlElement* style_element_; 00180 00182 GoogleString meta_tag_charset_; 00183 00185 CacheExtender* cache_extender_; 00186 ImageRewriteFilter* image_rewrite_filter_; 00187 ImageCombineFilter* image_combiner_; 00188 00192 Variable* num_blocks_rewritten_; 00194 Variable* num_parse_failures_; 00197 Variable* num_fallback_rewrites_; 00199 Variable* num_fallback_failures_; 00202 Variable* num_rewrites_dropped_; 00208 Variable* total_bytes_saved_; 00212 Variable* total_original_bytes_; 00215 Variable* num_uses_; 00217 Variable* num_flatten_imports_charset_mismatch_; 00219 Variable* num_flatten_imports_invalid_url_; 00221 Variable* num_flatten_imports_limit_exceeded_; 00223 Variable* num_flatten_imports_minify_failed_; 00225 Variable* num_flatten_imports_recursion_; 00227 Variable* num_flatten_imports_complex_queries_; 00228 00229 CssUrlEncoder encoder_; 00230 00231 DISALLOW_COPY_AND_ASSIGN(CssFilter); 00232 }; 00233 00235 class CssFilter::Context : public SingleRewriteContext { 00236 public: 00237 Context(CssFilter* filter, RewriteDriver* driver, 00238 RewriteContext* parent, 00239 CacheExtender* cache_extender, 00240 ImageRewriteFilter* image_rewriter, 00241 ImageCombineFilter* image_combiner, 00242 ResourceContext* context); 00243 virtual ~Context(); 00244 00246 void SetupInlineRewrite(HtmlElement* style_element, HtmlCharactersNode* text); 00247 void SetupAttributeRewrite(HtmlElement* element, 00248 HtmlElement::Attribute* src, 00249 InlineCssKind inline_css_kind); 00250 void SetupExternalRewrite(const GoogleUrl& base_gurl, 00251 const GoogleUrl& trim_gurl); 00252 00255 void RewriteCssFromNested(RewriteContext* parent, CssHierarchy* hierarchy); 00256 00259 virtual bool AbsolutifyIfNeeded(const StringPiece& input_contents, 00260 Writer* writer, MessageHandler* handler); 00261 00262 CssResourceSlotFactory* slot_factory() { return &slot_factory_; } 00263 00264 CssHierarchy* mutable_hierarchy() { return &hierarchy_; } 00265 00266 protected: 00267 virtual void Render(); 00268 virtual void Harvest(); 00269 virtual bool Partition(OutputPartitions* partitions, 00270 OutputResourceVector* outputs); 00271 virtual void RewriteSingle(const ResourcePtr& input, 00272 const OutputResourcePtr& output); 00273 virtual const char* id() const { return filter_->id(); } 00274 virtual OutputResourceKind kind() const { return kRewrittenResource; } 00275 virtual GoogleString CacheKeySuffix() const; 00276 virtual const UrlSegmentEncoder* encoder() const; 00277 00278 private: 00279 bool RewriteCssText(const GoogleUrl& css_base_gurl, 00280 const GoogleUrl& css_trim_gurl, 00281 const StringPiece& in_text, 00282 int64 in_text_size, 00283 bool text_is_declarations, 00284 MessageHandler* handler); 00285 00287 void RewriteCssFromRoot(const StringPiece& in_text, int64 in_text_size, 00288 bool has_unparseables, Css::Stylesheet* stylesheet); 00289 00295 bool FallbackRewriteUrls(const StringPiece& in_text); 00296 00299 bool SerializeCss(int64 in_text_size, 00300 const Css::Stylesheet* stylesheet, 00301 const GoogleUrl& css_base_gurl, 00302 const GoogleUrl& css_trim_gurl, 00303 bool previously_optimized, 00304 bool stylesheet_is_declarations, 00305 bool add_utf8_bom, 00306 GoogleString* out_text, 00307 MessageHandler* handler); 00308 00312 bool IsInlineAttribute() const { 00313 return (rewrite_inline_attribute_ != NULL); 00314 } 00315 00319 int64 ImageInlineMaxBytes() const { 00320 if (rewrite_inline_element_ != NULL) { 00322 return driver_->options()->ImageInlineMaxBytes(); 00323 } else { 00325 return driver_->options()->CssImageInlineMaxBytes(); 00326 } 00327 } 00328 00329 CssFilter* filter_; 00330 RewriteDriver* driver_; 00331 scoped_ptr<CssImageRewriter> css_image_rewriter_; 00332 CssResourceSlotFactory slot_factory_; 00333 CssHierarchy hierarchy_; 00334 bool css_rewritten_; 00335 bool has_utf8_bom_; 00336 00338 bool fallback_mode_; 00341 scoped_ptr<AssociationTransformer> fallback_transformer_; 00344 scoped_ptr<RewriteDomainTransformer> absolutifier_; 00345 00349 HtmlElement* rewrite_inline_element_; 00350 00352 HtmlCharactersNode* rewrite_inline_char_node_; 00353 00357 HtmlElement::Attribute* rewrite_inline_attribute_; 00358 00362 InlineCssKind rewrite_inline_css_kind_; 00363 00365 int64 in_text_size_; 00366 GoogleUrl css_base_gurl_; 00367 GoogleUrl css_trim_gurl_; 00368 ResourcePtr input_resource_; 00369 OutputResourcePtr output_resource_; 00370 00371 DISALLOW_COPY_AND_ASSIGN(Context); 00372 }; 00373 00374 } 00375 00376 #endif ///< NET_INSTAWEB_REWRITER_PUBLIC_CSS_FILTER_H_