Page Speed Optimization Libraries  1.7.30.3
net/instaweb/rewriter/public/css_flatten_imports_context.h
Go to the documentation of this file.
00001 /*
00002  * Copyright 2012 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_FLATTEN_IMPORTS_CONTEXT_H_
00020 #define NET_INSTAWEB_REWRITER_PUBLIC_CSS_FLATTEN_IMPORTS_CONTEXT_H_
00021 
00022 #include "base/logging.h"
00023 #include "net/instaweb/http/public/content_type.h"
00024 #include "net/instaweb/rewriter/cached_result.pb.h"
00025 #include "net/instaweb/rewriter/public/css_filter.h"
00026 #include "net/instaweb/rewriter/public/css_hierarchy.h"
00027 #include "net/instaweb/rewriter/public/css_tag_scanner.h"
00028 #include "net/instaweb/rewriter/public/output_resource_kind.h"
00029 #include "net/instaweb/rewriter/public/resource.h"
00030 #include "net/instaweb/rewriter/public/server_context.h"
00031 #include "net/instaweb/rewriter/public/rewrite_driver.h"
00032 #include "net/instaweb/rewriter/public/rewrite_options.h"
00033 #include "net/instaweb/rewriter/public/rewrite_result.h"
00034 #include "net/instaweb/rewriter/public/single_rewrite_context.h"
00035 #include "net/instaweb/rewriter/public/url_namer.h"
00036 #include "net/instaweb/util/public/basictypes.h"
00037 #include "net/instaweb/util/public/ref_counted_ptr.h"
00038 #include "net/instaweb/util/public/statistics.h"
00039 #include "net/instaweb/util/public/string.h"
00040 #include "net/instaweb/util/public/string_util.h"
00041 #include "pagespeed/kernel/base/string_writer.h"
00042 
00043 namespace net_instaweb {
00044 
00045 class RewriteContext;
00046 
00048 class CssFlattenImportsContext : public SingleRewriteContext {
00049  public:
00050   CssFlattenImportsContext(RewriteContext* parent,
00051                            CssFilter* filter,
00052                            CssFilter::Context* rewriter,
00053                            CssHierarchy* hierarchy)
00054       : SingleRewriteContext(NULL, parent, NULL ),
00055         filter_(filter),
00056         rewriter_(rewriter),
00057         hierarchy_(hierarchy) {
00058   }
00059   virtual ~CssFlattenImportsContext() {}
00060 
00061   virtual GoogleString CacheKeySuffix() const {
00066     GoogleString suffix;
00067     if (hierarchy_->media().empty()) {
00068       suffix = "all";
00069     } else {
00070       suffix = hierarchy_->media()[0];
00071       for (int i = 1, n = hierarchy_->media().size(); i < n; ++i) {
00072         StrAppend(&suffix, "_", hierarchy_->media()[i]);
00073       }
00074     }
00075     return suffix;
00076   }
00077 
00078   virtual void RewriteSingle(const ResourcePtr& input_resource,
00079                              const OutputResourcePtr& output_resource) {
00080     input_resource_ = input_resource;
00081     output_resource_ = output_resource;
00082 
00091     RewriteDomainTransformer transformer(&hierarchy_->css_base_url(),
00092                                          &hierarchy_->css_trim_url(),
00093                                          Driver());
00096     StringWriter writer(hierarchy_->input_contents_backing_store());
00099     if ( Driver()->server_context()->url_namer()->ProxyMode() ||
00100         !Driver()->options()->trim_urls_in_css() ||
00101         !Driver()->options()->Enabled(RewriteOptions::kLeftTrimUrls)) {
00102       transformer.set_trim_urls(false);
00103     }
00104     if (CssTagScanner::TransformUrls(input_resource_->contents(),
00105                                      &writer,
00106                                      &transformer,
00107                                      Driver()->message_handler())) {
00108       hierarchy_->set_input_contents_to_backing_store();
00109       hierarchy_->set_input_contents_resolved(true);
00110     } else {
00111       hierarchy_->set_input_contents(input_resource_->contents());
00112     }
00113 
00114     bool ok = true;
00115     GoogleString failure_reason;
00116     if (!hierarchy_->Parse()) {
00118       ok = false;
00119       failure_reason = StrCat("Cannot parse the CSS in ",
00120                               hierarchy_->url_for_humans());
00121       filter_->num_flatten_imports_minify_failed_->Add(1);
00122     } else if (!hierarchy_->CheckCharsetOk(input_resource, &failure_reason)) {
00123       ok = false;
00124       filter_->num_flatten_imports_charset_mismatch_->Add(1);
00125     } else {
00126       rewriter_->RewriteCssFromNested(this, hierarchy_);
00127     }
00128 
00129     if (!ok) {
00130       hierarchy_->set_flattening_succeeded(false);
00131       hierarchy_->AddFlatteningFailureReason(failure_reason);
00132       RewriteDone(kRewriteFailed, 0);
00133     } else if (num_nested() > 0) {
00134       StartNestedTasks(); 
00135     } else {
00136       Harvest(); 
00137     }
00138   }
00139 
00140   void Harvest() {
00141     DCHECK_EQ(1, num_output_partitions());
00142 
00148     hierarchy_->RollUpContents();
00149 
00151     output_partition(0)->set_inlined_data(hierarchy_->minified_contents());
00152 
00153     ServerContext* server_context = FindServerContext();
00154     server_context->MergeNonCachingResponseHeaders(input_resource_,
00155                                                    output_resource_);
00156     if (Driver()->Write(ResourceVector(1, input_resource_),
00157                         hierarchy_->minified_contents(),
00158                         &kContentTypeCss,
00159                         input_resource_->charset(),
00160                         output_resource_.get())) {
00161       RewriteDone(kRewriteOk, 0);
00162     } else {
00163       RewriteDone(kRewriteFailed, 0);
00164     }
00165   }
00166 
00167   virtual void Render() {
00169     if (num_output_partitions() == 1 && output_partition(0)->optimizable()) {
00179       if (hierarchy_->minified_contents().empty()) {
00180         hierarchy_->set_minified_contents(
00181             output_partition(0)->inlined_data());
00182         hierarchy_->set_input_contents(hierarchy_->minified_contents());
00183       }
00184     } else {
00190       hierarchy_->set_flattening_succeeded(false);
00191     }
00192   }
00193 
00194   virtual const char* id() const {
00195     return RewriteOptions::kCssImportFlattenerId;
00196   }
00197   virtual OutputResourceKind kind() const { return kRewrittenResource; }
00198 
00199  private:
00200   CssFilter* filter_;
00201   CssFilter::Context* rewriter_;
00202   CssHierarchy* hierarchy_;
00203   ResourcePtr input_resource_;
00204   OutputResourcePtr output_resource_;
00205   DISALLOW_COPY_AND_ASSIGN(CssFlattenImportsContext);
00206 };
00207 
00208 }  
00209 
00210 #endif  ///< NET_INSTAWEB_REWRITER_PUBLIC_CSS_FLATTEN_IMPORTS_CONTEXT_H_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines