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),
18
// morlovich@google.com (Maksim Orlovich)
20
// This filters helps inline a subset of CSS critical to initial rendering of
21
// the webpage by focusing only on declarations whose selectors match
22
// elements critical to such rendering. The full original CSS is moved to the
23
// foot of the webpage and lazy-loaded via JS.
25
#ifndef NET_INSTAWEB_REWRITER_PUBLIC_CRITICAL_SELECTOR_FILTER_H_
26
#define NET_INSTAWEB_REWRITER_PUBLIC_CRITICAL_SELECTOR_FILTER_H_
30
#include "net/instaweb/http/public/semantic_type.h"
31
#include "net/instaweb/rewriter/public/css_summarizer_base.h"
32
#include "net/instaweb/rewriter/public/rewrite_driver.h"
33
#include "net/instaweb/rewriter/public/rewrite_options.h"
34
#include "net/instaweb/util/public/basictypes.h"
35
#include "net/instaweb/util/public/string.h"
36
#include "net/instaweb/util/public/string_util.h"
44
namespace net_instaweb {
46
class HtmlCharactersNode;
49
class CriticalSelectorFilter : public CssSummarizerBase {
51
static const char kAddStylesFunction[];
52
static const char kAddStylesInvocation[];
53
static const char kApplyFlushEarlyCss[];
54
static const char kInvokeFlushEarlyCssTemplate[];
55
static const char kMoveScriptId[];
56
static const char kNoscriptStylesClass[];
58
explicit CriticalSelectorFilter(RewriteDriver* rewrite_driver);
59
virtual ~CriticalSelectorFilter();
61
virtual const char* Name() const { return "CriticalSelectorFilter"; }
62
virtual const char* id() const { return "cl"; }
64
// This filter needs access to all critical selectors (even those from
65
// unauthorized domains) in order to inline them into HTML.
66
// Inlining css from unauthorized domains into HTML is considered
67
// safe because it does not cause any new content to be executed compared
68
// to the unoptimized page.
69
virtual RewriteDriver::InlineAuthorizationPolicy AllowUnauthorizedDomain()
71
return driver()->options()->HasInlineUnauthorizedResourceType(
72
semantic_type::kStylesheet) ?
73
RewriteDriver::kInlineUnauthorizedResources :
74
RewriteDriver::kInlineOnlyAuthorizedResources;
77
// Selectors are inlined into the html.
78
virtual bool IntendedForInlining() const { return true; }
81
// Overrides of CssSummarizerBase summary API. These help us compute
82
// the critical portions of the various fragments in the page, and to
83
// write them out to the page. We also use this to pick up the output
84
// of filters before us, like rewrite_css; so we run this even on things
85
// that will not contain on-screen critical CSS.
86
virtual void Summarize(Css::Stylesheet* stylesheet,
87
GoogleString* out) const;
88
virtual void RenderSummary(int pos,
90
HtmlCharactersNode* char_node,
91
bool* is_element_deleted);
92
virtual void WillNotRenderSummary(int pos,
94
HtmlCharactersNode* char_node,
95
bool* is_element_deleted);
97
// Since our computation depends on the selectors that are relevant to the
98
// webpage, we incorporate them into the cache key as well.
99
virtual GoogleString CacheKeySuffix() const;
102
virtual void StartDocumentImpl();
103
virtual void EndDocument();
104
virtual void RenderDone();
106
// Filter control API.
107
virtual void DetermineEnabled(GoogleString* disabled_reason);
111
class CssStyleElement;
112
typedef std::vector<CssElement*> CssElementVector;
114
void RememberFullCss(int pos,
115
HtmlElement* element,
116
HtmlCharactersNode* char_node);
118
bool IsCssFlushedEarly(const GoogleString& url) const;
119
void ApplyCssFlushedEarly(HtmlElement* element,
120
const GoogleString& style_id,
123
// Selectors that are critical for this page.
124
// These are just copied over from the finder and turned into a set for easier
125
// membership checking.
126
StringSet critical_selectors_;
128
// Summary of critical_selectors_ as a short string.
129
GoogleString cache_key_suffix_;
131
// Info on all the CSS in the page, potentially as optimized by other filters.
132
// We will emit code to lazy-load it at the very end of the document.
133
// May contain NULL pointers.
134
CssElementVector css_elements_;
136
// True if EndDocument was called; helps us identify last flush window.
137
bool saw_end_document_;
139
// True if we rendered any block at all.
142
// True if flush early script to move links has been added.
143
bool is_flush_script_added_;
145
DISALLOW_COPY_AND_ASSIGN(CriticalSelectorFilter);
148
} // namespace net_instaweb
150
#endif // NET_INSTAWEB_REWRITER_PUBLIC_CRITICAL_SELECTOR_FILTER_H_