Page Speed Optimization Libraries
1.7.30.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, 00183 GoogleString* failure_reason) const; 00184 00187 bool GetApplicableMedia(const HtmlElement* element, 00188 StringVector* media) const; 00189 00190 bool in_style_element_; 00191 00192 HtmlElement* style_element_; 00193 00195 GoogleString meta_tag_charset_; 00196 00198 CacheExtender* cache_extender_; 00199 ImageRewriteFilter* image_rewrite_filter_; 00200 ImageCombineFilter* image_combiner_; 00201 00205 Variable* num_blocks_rewritten_; 00207 Variable* num_parse_failures_; 00210 Variable* num_fallback_rewrites_; 00212 Variable* num_fallback_failures_; 00215 Variable* num_rewrites_dropped_; 00221 Variable* total_bytes_saved_; 00225 Variable* total_original_bytes_; 00228 Variable* num_uses_; 00230 Variable* num_flatten_imports_charset_mismatch_; 00232 Variable* num_flatten_imports_invalid_url_; 00234 Variable* num_flatten_imports_limit_exceeded_; 00236 Variable* num_flatten_imports_minify_failed_; 00238 Variable* num_flatten_imports_recursion_; 00240 Variable* num_flatten_imports_complex_queries_; 00241 00242 CssUrlEncoder encoder_; 00243 00245 static const RewriteOptions::Filter* merged_filters_; 00246 static int merged_filters_size_; 00247 00249 static StringPieceVector* related_options_; 00250 00251 DISALLOW_COPY_AND_ASSIGN(CssFilter); 00252 }; 00253 00255 class CssFilter::Context : public SingleRewriteContext { 00256 public: 00257 Context(CssFilter* filter, RewriteDriver* driver, 00258 RewriteContext* parent, 00259 CacheExtender* cache_extender, 00260 ImageRewriteFilter* image_rewriter, 00261 ImageCombineFilter* image_combiner, 00262 ResourceContext* context); 00263 virtual ~Context(); 00264 00266 void SetupInlineRewrite(HtmlElement* style_element, HtmlCharactersNode* text); 00267 void SetupAttributeRewrite(HtmlElement* element, 00268 HtmlElement::Attribute* src, 00269 InlineCssKind inline_css_kind); 00270 void SetupExternalRewrite(HtmlElement* element, 00271 const GoogleUrl& base_gurl, 00272 const GoogleUrl& trim_gurl); 00273 00276 void RewriteCssFromNested(RewriteContext* parent, CssHierarchy* hierarchy); 00277 00280 virtual bool AbsolutifyIfNeeded(const StringPiece& input_contents, 00281 Writer* writer, MessageHandler* handler); 00282 00283 CssResourceSlotFactory* slot_factory() { return &slot_factory_; } 00284 00285 CssHierarchy* mutable_hierarchy() { return &hierarchy_; } 00286 00287 protected: 00288 virtual void Render(); 00289 virtual void Harvest(); 00290 virtual bool Partition(OutputPartitions* partitions, 00291 OutputResourceVector* outputs); 00292 virtual void RewriteSingle(const ResourcePtr& input, 00293 const OutputResourcePtr& output); 00294 virtual const char* id() const { return filter_->id(); } 00295 virtual OutputResourceKind kind() const { return kRewrittenResource; } 00296 virtual GoogleString CacheKeySuffix() const; 00297 virtual const UrlSegmentEncoder* encoder() const; 00298 00300 virtual GoogleString UserAgentCacheKey( 00301 const ResourceContext* resource_context) const; 00302 00303 private: 00304 bool RewriteCssText(const GoogleUrl& css_base_gurl, 00305 const GoogleUrl& css_trim_gurl, 00306 const StringPiece& in_text, 00307 int64 in_text_size, 00308 bool text_is_declarations, 00309 MessageHandler* handler); 00310 00312 void RewriteCssFromRoot(const StringPiece& in_text, int64 in_text_size, 00313 bool has_unparseables, Css::Stylesheet* stylesheet); 00314 00320 bool FallbackRewriteUrls(const StringPiece& in_text); 00321 00324 bool SerializeCss(int64 in_text_size, 00325 const Css::Stylesheet* stylesheet, 00326 const GoogleUrl& css_base_gurl, 00327 const GoogleUrl& css_trim_gurl, 00328 bool previously_optimized, 00329 bool stylesheet_is_declarations, 00330 bool add_utf8_bom, 00331 GoogleString* out_text, 00332 MessageHandler* handler); 00333 00337 bool IsInlineAttribute() const { 00338 return (rewrite_inline_attribute_ != NULL); 00339 } 00340 00344 int64 ImageInlineMaxBytes() const; 00345 00346 CssFilter* filter_; 00347 RewriteDriver* driver_; 00348 scoped_ptr<CssImageRewriter> css_image_rewriter_; 00349 CssResourceSlotFactory slot_factory_; 00350 CssHierarchy hierarchy_; 00351 bool css_rewritten_; 00352 bool has_utf8_bom_; 00353 00355 bool fallback_mode_; 00358 scoped_ptr<AssociationTransformer> fallback_transformer_; 00361 scoped_ptr<RewriteDomainTransformer> absolutifier_; 00362 00365 HtmlElement* rewrite_element_; 00366 00370 HtmlElement* rewrite_inline_element_; 00371 00373 HtmlCharactersNode* rewrite_inline_char_node_; 00374 00378 HtmlElement::Attribute* rewrite_inline_attribute_; 00379 00383 InlineCssKind rewrite_inline_css_kind_; 00384 00386 int64 in_text_size_; 00387 GoogleUrl css_base_gurl_; 00388 GoogleUrl css_trim_gurl_; 00389 ResourcePtr input_resource_; 00390 OutputResourcePtr output_resource_; 00391 00392 DISALLOW_COPY_AND_ASSIGN(Context); 00393 }; 00394 00395 } 00396 00397 #endif ///< NET_INSTAWEB_REWRITER_PUBLIC_CSS_FILTER_H_