blob: 98f27e077e8c47563275e9ad1e1a080612bfddf4 [file] [log] [blame]
/*
* Copyright 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Author: abliss@google.com (Adam Bliss)
#ifndef NET_INSTAWEB_REWRITER_PUBLIC_IMAGE_COMBINE_FILTER_H_
#define NET_INSTAWEB_REWRITER_PUBLIC_IMAGE_COMBINE_FILTER_H_
#include "net/instaweb/rewriter/public/css_filter.h"
#include "net/instaweb/rewriter/public/rewrite_filter.h"
#include "net/instaweb/rewriter/public/rewrite_options.h"
#include "net/instaweb/rewriter/public/server_context.h"
#include "pagespeed/kernel/base/basictypes.h"
#include "pagespeed/kernel/base/string_util.h"
#include "pagespeed/kernel/util/url_multipart_encoder.h"
namespace Css {
class Declarations;
class Values;
} // namespace Css
namespace net_instaweb {
class GoogleUrl;
class HtmlElement;
class MessageHandler;
class RewriteContext;
class RewriteDriver;
class Statistics;
class UrlSegmentEncoder;
class Variable;
/*
* The ImageCombineFilter combines multiple images into a single image
* (a process called "spriting". This reduces the total number of
* round-trips, and reduces bytes downloaded by consolidating image
* headers and improving compression.
*
* Right now this is only used on CSS background-images, so it doesn't
* need to be in the HTML filter chain. In the future it will rewrite
* img tags as well.
*/
class ImageCombineFilter : public RewriteFilter {
public:
explicit ImageCombineFilter(RewriteDriver* rewrite_driver);
virtual ~ImageCombineFilter();
static void InitStats(Statistics* statistics);
// Attempt to add the CSS background image with (resolved) url original_url to
// this partnership. We do not take ownership of declarations; it must live
// until you call Realize() or Reset(). declarations is where we will add the
// new width and height values; url_value must point to the URL value to be
// replaced. Will not actually change anything until you call Realize().
// This will succeed even in cases when it turns out (later) the image
// can not be sprited. Fails and returns false if:
// * We cannot get the declaration dimensions from 'decls'.
// * original_url is not on an authorized domain.
// * There is already a slot for original_url.
bool AddCssBackgroundContext(const GoogleUrl& original_url,
const GoogleUrl& base_url,
Css::Values* values,
int value_index,
CssFilter::Context* parent,
Css::Declarations* decls,
bool* is_authorized,
MessageHandler* handler);
// Create the combination with the current combiner.
OutputResourcePtr MakeOutput();
// Creates a new context for doing spriting, but does not register it.
void Reset(RewriteContext* context, const GoogleUrl& css_url,
const StringPiece& css_text);
// If there is any work to do, registers the RewriteContext created by
// Reset(). If there isn't, cleans it up.
void RegisterOrReleaseContext();
protected:
virtual const UrlSegmentEncoder* encoder() const { return &encoder_; }
virtual const char* Name() const { return "ImageCombine"; }
virtual void StartDocumentImpl() {}
virtual void StartElementImpl(HtmlElement* element) {}
virtual void EndElementImpl(HtmlElement* element) {}
// Image rewriting was originally, but is no longer, a single CSS.
virtual const char* id() const { return RewriteOptions::kImageCombineId; }
private:
class Combiner;
class Context;
virtual RewriteContext* MakeRewriteContext();
Context* MakeNestedContext(RewriteContext* parent, const GoogleUrl& css_url,
const StringPiece& css_text);
bool GetDeclarationDimensions(Css::Declarations* declarations,
int* width, int* height);
void AddFilesReducedStat(int reduced);
Variable* image_file_count_reduction_;
Context* context_;
UrlMultipartEncoder encoder_;
DISALLOW_COPY_AND_ASSIGN(ImageCombineFilter);
};
} // namespace net_instaweb
#endif // NET_INSTAWEB_REWRITER_PUBLIC_IMAGE_COMBINE_FILTER_H_