Page Speed Optimization Libraries
1.4.26.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_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 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 void EncodeUserAgentIntoResourceContext( 00107 ResourceContext* context) const; 00108 00109 static const char kBlocksRewritten[]; 00110 static const char kParseFailures[]; 00111 static const char kFallbackRewrites[]; 00112 static const char kFallbackFailures[]; 00113 static const char kRewritesDropped[]; 00114 static const char kTotalBytesSaved[]; 00115 static const char kTotalOriginalBytes[]; 00116 static const char kUses[]; 00117 static const char kCharsetMismatch[]; 00118 static const char kInvalidUrl[]; 00119 static const char kLimitExceeded[]; 00120 static const char kMinifyFailed[]; 00121 static const char kRecursion[]; 00122 static const char kComplexQueries[]; 00123 00124 RewriteContext* MakeNestedFlatteningContextInNewSlot( 00125 const ResourcePtr& resource, const GoogleString& location, 00126 CssFilter::Context* rewriter, RewriteContext* parent, 00127 CssHierarchy* hierarchy); 00128 00129 virtual const RewriteOptions::Filter* RelatedFilters(int* num_filters) const; 00130 virtual const RewriteOptions::OptionEnum* RelatedOptions( 00131 int* num_options) const; 00132 00133 protected: 00134 virtual RewriteContext* MakeRewriteContext(); 00135 virtual const UrlSegmentEncoder* encoder() const; 00136 virtual RewriteContext* MakeNestedRewriteContext( 00137 RewriteContext* parent, const ResourceSlotPtr& slot); 00138 00139 private: 00140 friend class Context; 00141 friend class CssFlattenImportsContext; 00142 friend class CssHierarchy; 00143 00144 enum InlineCssKind { 00145 kInsideStyleTag, 00146 kAttributeWithoutUrls, 00147 kAttributeWithUrls 00148 }; 00149 00150 Context* MakeContext(RewriteDriver* driver, 00151 RewriteContext* parent); 00152 00154 void StartInlineRewrite(HtmlCharactersNode* text); 00155 00158 void StartAttributeRewrite(HtmlElement* element, 00159 HtmlElement::Attribute* style, 00160 InlineCssKind inline_css_kind); 00161 00164 void StartExternalRewrite(HtmlElement* link, HtmlElement::Attribute* src); 00165 00166 ResourceSlot* MakeSlotForInlineCss(const StringPiece& content); 00167 CssFilter::Context* StartRewriting(const ResourceSlotPtr& slot); 00168 00174 bool GetApplicableCharset(const HtmlElement* element, 00175 GoogleString* charset) const; 00176 00179 bool GetApplicableMedia(const HtmlElement* element, 00180 StringVector* media) const; 00181 00182 bool in_style_element_; 00183 00184 HtmlElement* style_element_; 00185 00187 GoogleString meta_tag_charset_; 00188 00190 CacheExtender* cache_extender_; 00191 ImageRewriteFilter* image_rewrite_filter_; 00192 ImageCombineFilter* image_combiner_; 00193 00197 Variable* num_blocks_rewritten_; 00199 Variable* num_parse_failures_; 00202 Variable* num_fallback_rewrites_; 00204 Variable* num_fallback_failures_; 00207 Variable* num_rewrites_dropped_; 00213 Variable* total_bytes_saved_; 00217 Variable* total_original_bytes_; 00220 Variable* num_uses_; 00222 Variable* num_flatten_imports_charset_mismatch_; 00224 Variable* num_flatten_imports_invalid_url_; 00226 Variable* num_flatten_imports_limit_exceeded_; 00228 Variable* num_flatten_imports_minify_failed_; 00230 Variable* num_flatten_imports_recursion_; 00232 Variable* num_flatten_imports_complex_queries_; 00233 00234 CssUrlEncoder encoder_; 00235 00236 DISALLOW_COPY_AND_ASSIGN(CssFilter); 00237 }; 00238 00240 class CssFilter::Context : public SingleRewriteContext { 00241 public: 00242 Context(CssFilter* filter, RewriteDriver* driver, 00243 RewriteContext* parent, 00244 CacheExtender* cache_extender, 00245 ImageRewriteFilter* image_rewriter, 00246 ImageCombineFilter* image_combiner, 00247 ResourceContext* context); 00248 virtual ~Context(); 00249 00251 void SetupInlineRewrite(HtmlElement* style_element, HtmlCharactersNode* text); 00252 void SetupAttributeRewrite(HtmlElement* element, 00253 HtmlElement::Attribute* src, 00254 InlineCssKind inline_css_kind); 00255 void SetupExternalRewrite(const GoogleUrl& base_gurl, 00256 const GoogleUrl& trim_gurl); 00257 00260 void RewriteCssFromNested(RewriteContext* parent, CssHierarchy* hierarchy); 00261 00264 virtual bool AbsolutifyIfNeeded(const StringPiece& input_contents, 00265 Writer* writer, MessageHandler* handler); 00266 00267 CssResourceSlotFactory* slot_factory() { return &slot_factory_; } 00268 00269 CssHierarchy* mutable_hierarchy() { return &hierarchy_; } 00270 00271 protected: 00272 virtual void Render(); 00273 virtual void Harvest(); 00274 virtual bool Partition(OutputPartitions* partitions, 00275 OutputResourceVector* outputs); 00276 virtual void RewriteSingle(const ResourcePtr& input, 00277 const OutputResourcePtr& output); 00278 virtual const char* id() const { return filter_->id(); } 00279 virtual OutputResourceKind kind() const { return kRewrittenResource; } 00280 virtual GoogleString CacheKeySuffix() const; 00281 virtual const UrlSegmentEncoder* encoder() const; 00282 00284 virtual GoogleString UserAgentCacheKey( 00285 const ResourceContext* resource_context) const; 00286 00287 private: 00288 bool RewriteCssText(const GoogleUrl& css_base_gurl, 00289 const GoogleUrl& css_trim_gurl, 00290 const StringPiece& in_text, 00291 int64 in_text_size, 00292 bool text_is_declarations, 00293 MessageHandler* handler); 00294 00296 void RewriteCssFromRoot(const StringPiece& in_text, int64 in_text_size, 00297 bool has_unparseables, Css::Stylesheet* stylesheet); 00298 00304 bool FallbackRewriteUrls(const StringPiece& in_text); 00305 00308 bool SerializeCss(int64 in_text_size, 00309 const Css::Stylesheet* stylesheet, 00310 const GoogleUrl& css_base_gurl, 00311 const GoogleUrl& css_trim_gurl, 00312 bool previously_optimized, 00313 bool stylesheet_is_declarations, 00314 bool add_utf8_bom, 00315 GoogleString* out_text, 00316 MessageHandler* handler); 00317 00321 bool IsInlineAttribute() const { 00322 return (rewrite_inline_attribute_ != NULL); 00323 } 00324 00328 int64 ImageInlineMaxBytes() const; 00329 00330 CssFilter* filter_; 00331 RewriteDriver* driver_; 00332 scoped_ptr<CssImageRewriter> css_image_rewriter_; 00333 CssResourceSlotFactory slot_factory_; 00334 CssHierarchy hierarchy_; 00335 bool css_rewritten_; 00336 bool has_utf8_bom_; 00337 00339 bool fallback_mode_; 00342 scoped_ptr<AssociationTransformer> fallback_transformer_; 00345 scoped_ptr<RewriteDomainTransformer> absolutifier_; 00346 00350 HtmlElement* rewrite_inline_element_; 00351 00353 HtmlCharactersNode* rewrite_inline_char_node_; 00354 00358 HtmlElement::Attribute* rewrite_inline_attribute_; 00359 00363 InlineCssKind rewrite_inline_css_kind_; 00364 00366 int64 in_text_size_; 00367 GoogleUrl css_base_gurl_; 00368 GoogleUrl css_trim_gurl_; 00369 ResourcePtr input_resource_; 00370 OutputResourcePtr output_resource_; 00371 00372 DISALLOW_COPY_AND_ASSIGN(Context); 00373 }; 00374 00375 } 00376 00377 #endif ///< NET_INSTAWEB_REWRITER_PUBLIC_CSS_FILTER_H_