2
* Copyright 2013 Google Inc.
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
* you may not use this file except in compliance with the License.
6
* You may obtain a copy of the License at
8
* http://www.apache.org/licenses/LICENSE-2.0
10
* Unless required by applicable law or agreed to in writing, software
11
* distributed under the License is distributed on an "AS IS" BASIS,
12
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
* See the License for the specific language governing permissions and
14
* limitations under the License.
17
// Author: slamm@google.com (Stephen Lamm)
19
// Replace link tags with the inline CSS that is resolved on initial load.
20
// Move the link tags to the bottom (usually CSS is placed in HEAD). Also,
21
// copy existing inline style blocks to the bottom to maintain the original
24
// TODO(slamm): Consider prioritizing the rules in inline style blocks too.
26
// This lessons the extern resources in the HEAD and allows the page to load
30
#ifndef NET_INSTAWEB_REWRITER_PUBLIC_CRITICAL_CSS_FILTER_H_
31
#define NET_INSTAWEB_REWRITER_PUBLIC_CRITICAL_CSS_FILTER_H_
36
#include "net/instaweb/rewriter/critical_css.pb.h"
37
#include "net/instaweb/rewriter/public/css_tag_scanner.h"
38
#include "net/instaweb/rewriter/public/common_filter.h"
39
#include "net/instaweb/util/public/basictypes.h"
40
#include "net/instaweb/util/public/string.h"
42
namespace net_instaweb {
44
class CriticalCssFinder;
45
class CriticalCssResult;
46
class CriticalCssResult_LinkRules;
47
class HtmlCharactersNode;
51
class CriticalCssFilter : public CommonFilter {
53
explicit CriticalCssFilter(RewriteDriver* rewrite_driver,
54
CriticalCssFinder* finder);
55
virtual ~CriticalCssFilter();
57
static const char kAddStylesScript[];
58
static const char kStatsScriptTemplate[];
60
// Overridden from CommonFilter:
61
virtual void DetermineEnabled(GoogleString* disabled_reason);
62
virtual void StartDocumentImpl();
63
virtual void EndDocument();
64
virtual void StartElementImpl(HtmlElement* element);
65
virtual void EndElementImpl(HtmlElement* element);
66
virtual void Characters(HtmlCharactersNode* characters);
68
virtual const char* Name() const { return "CriticalCss"; }
71
// Decodes the link tag into a valid url.
72
GoogleString DecodeUrl(const GoogleString& url);
74
// Returns the critical CSS rules for the |decoded_url| of a <link> tag.
75
// If data is unavailable (e.g., not yet determined, or flushed from
76
// page property cache), the returned value is NULL.
77
const CriticalCssResult_LinkRules* GetLinkRules(
78
const GoogleString& decoded_url);
80
// Log the status of an attempt to rewrite.
81
// TODO(gee): This probably belongs in an ancestor class.
82
void LogRewrite(int status);
84
CssTagScanner css_tag_scanner_;
85
CriticalCssFinder* finder_;
87
CriticalCssResult* critical_css_result_;
89
// Map link URLs to indexes in the critical CSS result.
90
typedef std::map<GoogleString, int> UrlIndexes;
91
UrlIndexes url_indexes_;
93
bool has_critical_css_;
94
bool is_move_link_script_added_;
97
class CssStyleElement;
98
typedef std::vector<CssElement*> CssElementVector;
99
CssElementVector css_elements_;
100
CssStyleElement* current_style_element_;
102
// TODO(slamm): Are these just for logging, or do you want to export these
103
// to varz as well. Just in general, I think someone intimately familiar with
104
// this filter needs to make a pass and figure out what we should be
106
int total_critical_size_;
107
int total_original_size_;
108
int repeated_style_blocks_size_;
109
int num_repeated_style_blocks_;
111
int num_replaced_links_;
113
DISALLOW_COPY_AND_ASSIGN(CriticalCssFilter);
116
} // namespace net_instaweb
118
#endif // NET_INSTAWEB_REWRITER_PUBLIC_CRITICAL_CSS_FILTER_H_