Page Speed Optimization Libraries
1.6.29.3
|
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 CssImageRewriter; 00049 class CacheExtender; 00050 class HtmlCharactersNode; 00051 class ImageCombineFilter; 00052 class ImageRewriteFilter; 00053 class MessageHandler; 00054 class OutputPartitions; 00055 class ResourceContext; 00056 class RewriteContext; 00057 class RewriteDriver; 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 00095 static void AddRelatedOptions(StringPieceVector* target); 00096 00100 static void InitializeAtExitManager(); 00101 00102 virtual void StartDocumentImpl(); 00103 virtual void StartElementImpl(HtmlElement* element); 00104 virtual void Characters(HtmlCharactersNode* characters); 00105 virtual void EndElementImpl(HtmlElement* element); 00106 00107 virtual const char* Name() const { return "CssFilter"; } 00108 virtual const char* id() const { return RewriteOptions::kCssFilterId; } 00109 virtual void EncodeUserAgentIntoResourceContext( 00110 ResourceContext* context) const; 00111 00112 static const char kBlocksRewritten[]; 00113 static const char kParseFailures[]; 00114 static const char kFallbackRewrites[]; 00115 static const char kFallbackFailures[]; 00116 static const char kRewritesDropped[]; 00117 static const char kTotalBytesSaved[]; 00118 static const char kTotalOriginalBytes[]; 00119 static const char kUses[]; 00120 static const char kCharsetMismatch[]; 00121 static const char kInvalidUrl[]; 00122 static const char kLimitExceeded[]; 00123 static const char kMinifyFailed[]; 00124 static const char kRecursion[]; 00125 static const char kComplexQueries[]; 00126 00127 RewriteContext* MakeNestedFlatteningContextInNewSlot( 00128 const ResourcePtr& resource, const GoogleString& location, 00129 CssFilter::Context* rewriter, RewriteContext* parent, 00130 CssHierarchy* hierarchy); 00131 00132 virtual const RewriteOptions::Filter* RelatedFilters(int* num_filters) const { 00133 *num_filters = merged_filters_size_; 00134 return merged_filters_; 00135 } 00136 virtual const StringPieceVector* RelatedOptions() const { 00137 return related_options_; 00138 } 00139 00140 protected: 00141 virtual RewriteContext* MakeRewriteContext(); 00142 virtual const UrlSegmentEncoder* encoder() const; 00143 virtual RewriteContext* MakeNestedRewriteContext( 00144 RewriteContext* parent, const ResourceSlotPtr& slot); 00145 00146 private: 00147 friend class Context; 00148 friend class CssFlattenImportsContext; 00149 friend class CssHierarchy; 00150 00151 enum InlineCssKind { 00152 kInsideStyleTag, 00153 kAttributeWithoutUrls, 00154 kAttributeWithUrls 00155 }; 00156 00157 Context* MakeContext(RewriteDriver* driver, 00158 RewriteContext* parent); 00159 00161 void StartInlineRewrite(HtmlCharactersNode* text); 00162 00165 void StartAttributeRewrite(HtmlElement* element, 00166 HtmlElement::Attribute* style, 00167 InlineCssKind inline_css_kind); 00168 00171 void StartExternalRewrite(HtmlElement* link, HtmlElement::Attribute* src); 00172 00173 ResourceSlot* MakeSlotForInlineCss(const StringPiece& content); 00174 CssFilter::Context* StartRewriting(const ResourceSlotPtr& slot); 00175 00181 bool GetApplicableCharset(const HtmlElement* element, 00182 GoogleString* charset) const; 00183 00186 bool GetApplicableMedia(const HtmlElement* element, 00187 StringVector* media) const; 00188 00189 bool in_style_element_; 00190 00191 HtmlElement* style_element_; 00192 00194 GoogleString meta_tag_charset_; 00195 00197 CacheExtender* cache_extender_; 00198 ImageRewriteFilter* image_rewrite_filter_; 00199 ImageCombineFilter* image_combiner_; 00200 00204 Variable* num_blocks_rewritten_; 00206 Variable* num_parse_failures_; 00209 Variable* num_fallback_rewrites_; 00211 Variable* num_fallback_failures_; 00214 Variable* num_rewrites_dropped_; 00220 Variable* total_bytes_saved_; 00224 Variable* total_original_bytes_; 00227 Variable* num_uses_; 00229 Variable* num_flatten_imports_charset_mismatch_; 00231 Variable* num_flatten_imports_invalid_url_; 00233 Variable* num_flatten_imports_limit_exceeded_; 00235 Variable* num_flatten_imports_minify_failed_; 00237 Variable* num_flatten_imports_recursion_; 00239 Variable* num_flatten_imports_complex_queries_; 00240 00241 CssUrlEncoder encoder_; 00242 00244 static const RewriteOptions::Filter* merged_filters_; 00245 static int merged_filters_size_; 00246 00248 static StringPieceVector* related_options_; 00249 00250 DISALLOW_COPY_AND_ASSIGN(CssFilter); 00251 }; 00252 00254 class CssFilter::Context : public SingleRewriteContext { 00255 public: 00256 Context(CssFilter* filter, RewriteDriver* driver, 00257 RewriteContext* parent, 00258 CacheExtender* cache_extender, 00259 ImageRewriteFilter* image_rewriter, 00260 ImageCombineFilter* image_combiner, 00261 ResourceContext* context); 00262 virtual ~Context(); 00263 00265 void SetupInlineRewrite(HtmlElement* style_element, HtmlCharactersNode* text); 00266 void SetupAttributeRewrite(HtmlElement* element, 00267 HtmlElement::Attribute* src, 00268 InlineCssKind inline_css_kind); 00269 void SetupExternalRewrite(const GoogleUrl& base_gurl, 00270 const GoogleUrl& trim_gurl); 00271 00274 void RewriteCssFromNested(RewriteContext* parent, CssHierarchy* hierarchy); 00275 00278 virtual bool AbsolutifyIfNeeded(const StringPiece& input_contents, 00279 Writer* writer, MessageHandler* handler); 00280 00281 CssResourceSlotFactory* slot_factory() { return &slot_factory_; } 00282 00283 CssHierarchy* mutable_hierarchy() { return &hierarchy_; } 00284 00285 protected: 00286 virtual void Render(); 00287 virtual void Harvest(); 00288 virtual bool Partition(OutputPartitions* partitions, 00289 OutputResourceVector* outputs); 00290 virtual void RewriteSingle(const ResourcePtr& input, 00291 const OutputResourcePtr& output); 00292 virtual const char* id() const { return filter_->id(); } 00293 virtual OutputResourceKind kind() const { return kRewrittenResource; } 00294 virtual GoogleString CacheKeySuffix() const; 00295 virtual const UrlSegmentEncoder* encoder() const; 00296 00298 virtual GoogleString UserAgentCacheKey( 00299 const ResourceContext* resource_context) const; 00300 00301 private: 00302 bool RewriteCssText(const GoogleUrl& css_base_gurl, 00303 const GoogleUrl& css_trim_gurl, 00304 const StringPiece& in_text, 00305 int64 in_text_size, 00306 bool text_is_declarations, 00307 MessageHandler* handler); 00308 00310 void RewriteCssFromRoot(const StringPiece& in_text, int64 in_text_size, 00311 bool has_unparseables, Css::Stylesheet* stylesheet); 00312 00318 bool FallbackRewriteUrls(const StringPiece& in_text); 00319 00322 bool SerializeCss(int64 in_text_size, 00323 const Css::Stylesheet* stylesheet, 00324 const GoogleUrl& css_base_gurl, 00325 const GoogleUrl& css_trim_gurl, 00326 bool previously_optimized, 00327 bool stylesheet_is_declarations, 00328 bool add_utf8_bom, 00329 GoogleString* out_text, 00330 MessageHandler* handler); 00331 00335 bool IsInlineAttribute() const { 00336 return (rewrite_inline_attribute_ != NULL); 00337 } 00338 00342 int64 ImageInlineMaxBytes() const; 00343 00344 CssFilter* filter_; 00345 RewriteDriver* driver_; 00346 scoped_ptr<CssImageRewriter> css_image_rewriter_; 00347 CssResourceSlotFactory slot_factory_; 00348 CssHierarchy hierarchy_; 00349 bool css_rewritten_; 00350 bool has_utf8_bom_; 00351 00353 bool fallback_mode_; 00356 scoped_ptr<AssociationTransformer> fallback_transformer_; 00359 scoped_ptr<RewriteDomainTransformer> absolutifier_; 00360 00364 HtmlElement* rewrite_inline_element_; 00365 00367 HtmlCharactersNode* rewrite_inline_char_node_; 00368 00372 HtmlElement::Attribute* rewrite_inline_attribute_; 00373 00377 InlineCssKind rewrite_inline_css_kind_; 00378 00380 int64 in_text_size_; 00381 GoogleUrl css_base_gurl_; 00382 GoogleUrl css_trim_gurl_; 00383 ResourcePtr input_resource_; 00384 OutputResourcePtr output_resource_; 00385 00386 DISALLOW_COPY_AND_ASSIGN(Context); 00387 }; 00388 00389 } 00390 00391 #endif ///< NET_INSTAWEB_REWRITER_PUBLIC_CSS_FILTER_H_