~alinuxninja/nginx-edge/trunk

« back to all changes in this revision

Viewing changes to debian/modules/ngx_pagespeed/psol/include/net/instaweb/rewriter/public/css_summarizer_base.h

  • Committer: Vivian
  • Date: 2015-12-04 18:20:11 UTC
  • Revision ID: git-v1:a36f2bc32e884f7473b3a47040e5411306144d7d
* Do not extract psol.tar.gz

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright 2013 Google Inc.
3
 
 *
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
7
 
 *
8
 
 *      http://www.apache.org/licenses/LICENSE-2.0
9
 
 *
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.
15
 
 */
16
 
 
17
 
// Author: morlovich@google.com (Maksim Orlovich)
18
 
 
19
 
#ifndef NET_INSTAWEB_REWRITER_PUBLIC_CSS_SUMMARIZER_BASE_H_
20
 
#define NET_INSTAWEB_REWRITER_PUBLIC_CSS_SUMMARIZER_BASE_H_
21
 
 
22
 
#include <vector>
23
 
 
24
 
#include "net/instaweb/htmlparse/public/html_element.h"
25
 
#include "net/instaweb/rewriter/public/resource_slot.h"
26
 
#include "net/instaweb/rewriter/public/rewrite_filter.h"
27
 
#include "net/instaweb/util/public/basictypes.h"
28
 
#include "net/instaweb/util/public/scoped_ptr.h"
29
 
#include "net/instaweb/util/public/string.h"
30
 
#include "net/instaweb/util/public/string_util.h"
31
 
 
32
 
namespace Css {
33
 
 
34
 
class Stylesheet;
35
 
 
36
 
}  // namespace Css
37
 
 
38
 
namespace net_instaweb {
39
 
 
40
 
class AbstractMutex;
41
 
class HtmlCharactersNode;
42
 
class RewriteContext;
43
 
class RewriteDriver;
44
 
class Statistics;
45
 
class Variable;
46
 
 
47
 
// This class helps implement filters that try to compute some properties of all
48
 
// the screen-affecting CSS in the page except for scoped <style> blocks (which
49
 
// are left untouched). They are expected to override Summarize() to perform the
50
 
// per-CSS computation; then at SummariesDone() they can lookup summaries via
51
 
// NumStyles/GetSummaryForStyle.
52
 
class CssSummarizerBase : public RewriteFilter {
53
 
 public:
54
 
  static const char kNumCssUsedForCriticalCssComputation[];
55
 
  static const char kNumCssNotUsedForCriticalCssComputation[];
56
 
 
57
 
  explicit CssSummarizerBase(RewriteDriver* driver);
58
 
  virtual ~CssSummarizerBase();
59
 
 
60
 
  static void InitStats(Statistics* statistics);
61
 
 
62
 
 protected:
63
 
  enum SummaryState {
64
 
    // All OK!
65
 
    kSummaryOk,
66
 
 
67
 
    // Computation/Fetches ongoing, we don't have a result yet.
68
 
    kSummaryStillPending,
69
 
 
70
 
    // CSS parse error we can't recover from.
71
 
    kSummaryCssParseError,
72
 
 
73
 
    // Could not create the resource object, so its URL is malformed or we do
74
 
    // not have permission to rewrite it.
75
 
    kSummaryResourceCreationFailed,
76
 
 
77
 
    // Fetch result unusable, either error or not cacheable.
78
 
    kSummaryInputUnavailable,
79
 
 
80
 
    // Slot got removed by an another optimization.
81
 
    kSummarySlotRemoved,
82
 
  };
83
 
 
84
 
  struct SummaryInfo {
85
 
    SummaryInfo()
86
 
        : state(kSummaryStillPending),
87
 
          is_external(false),
88
 
          is_inside_noscript(false) {}
89
 
 
90
 
    // data actually computed by the subclass's Summarize method. Make sure to
91
 
    // check state == kSummaryOk before using it.
92
 
    GoogleString data;
93
 
 
94
 
    // State of computation of 'data'.
95
 
    SummaryState state;
96
 
 
97
 
    // Human-readable description of the location of the CSS. For use in debug
98
 
    // messages.
99
 
    GoogleString location;
100
 
 
101
 
    // Base to use for resolving links in the CSS resource.
102
 
    GoogleString base;
103
 
 
104
 
    // CSS media there were applied to the resource by the HTML.
105
 
    GoogleString media_from_html;
106
 
 
107
 
    // If it's an external stylesheet, the value of the rel attribute
108
 
    GoogleString rel;
109
 
 
110
 
    // True if it's a <link rel=stylesheet href=>, false for <style>
111
 
    bool is_external;
112
 
 
113
 
    // True if the style was included inside a noscript section.
114
 
    bool is_inside_noscript;
115
 
  };
116
 
 
117
 
  // This method should be overridden in case the subclass's summary computation
118
 
  // depends on things other than the input CSS.
119
 
  virtual GoogleString CacheKeySuffix() const;
120
 
 
121
 
  // This method should be overridden if some CSS should not go through the
122
 
  // summarization process (eg because it uses an inapplicable media type and
123
 
  // we'll just throw it away when we're done anyway).  By default all CSS
124
 
  // must be summarized.
125
 
  virtual bool MustSummarize(HtmlElement* element) const {
126
 
    return true;
127
 
  }
128
 
 
129
 
  // This should be overridden to compute a per-resource summary.
130
 
  // The method should not modify the object state, and only
131
 
  // put the result into *out as it may not be invoked in case of a
132
 
  // cache hit. The subclass may mutate *stylesheet if it so wishes.
133
 
  //
134
 
  // Note: this is called on a rewrite thread, so it should not access
135
 
  // HTML parser state.
136
 
  virtual void Summarize(Css::Stylesheet* stylesheet,
137
 
                         GoogleString* out) const = 0;
138
 
 
139
 
  // This can be optionally overridden to modify a CSS element based on a
140
 
  // successfully computed summary. It might not be invoked if cached
141
 
  // information is not readily available, and will not be invoked if CSS
142
 
  // parsing failed or some other error occurred. Invocation occurs from a
143
 
  // thread with HTML parser context state, so both DOM modification and
144
 
  // GetSummaryForStyle() are safe to use. If invoked, the method will be called
145
 
  // before SummariesDone().
146
 
  //
147
 
  // pos is the position of the element in the summary table.
148
 
  //
149
 
  // element points to the <link> or <style> element that was summarized.
150
 
  // If the element was a <style>, char_node will also point to its contents
151
 
  // node; otherwise it will be NULL. Overrides need to set is_element_deleted
152
 
  // to true if they delete the element.
153
 
  //
154
 
  // The default implementation does nothing.
155
 
  virtual void RenderSummary(int pos,
156
 
                             HtmlElement* element,
157
 
                             HtmlCharactersNode* char_node,
158
 
                             bool* is_element_deleted);
159
 
 
160
 
  // Like RenderSummary, but called in cases where we're unable to render a
161
 
  // summary for some reason (including not being able to compute one).
162
 
  // Note: not called when we're canceled due to disable_further_processing.
163
 
  //
164
 
  // Like with RenderSummary, this corresponds to entry [pos] in the summary
165
 
  // table, and elements points to the <link> or <style> containing CSS,
166
 
  // with char_node being non-null in case it was a <style>.  Overrides need
167
 
  // to set is_element_deleted to true if they delete the element.
168
 
  virtual void WillNotRenderSummary(int pos,
169
 
                                    HtmlElement* element,
170
 
                                    HtmlCharactersNode* char_node,
171
 
                                    bool* is_element_deleted);
172
 
 
173
 
  // This is called at the end of the document when all outstanding summary
174
 
  // computations have completed, regardless of whether successful or not. It
175
 
  // will not be called at all if they are still ongoing, however.
176
 
  //
177
 
  // It's called from a context which allows HTML parser state access.  You can
178
 
  // insert things at end of document by constructing an HtmlNode* using the
179
 
  // factories in HtmlParse and calling CommonFilter::InsertNodeAtBodyEnd(node).
180
 
  //
181
 
  // Note that the timing of this can vary widely --- it can occur during
182
 
  // initial parse, during the render phase, or even at RenderDone, so
183
 
  // implementors should not make assumptions about what other filters may have
184
 
  // done to the DOM.
185
 
  //
186
 
  // Base version does nothing.
187
 
  virtual void SummariesDone();
188
 
 
189
 
  // Returns total number of <link> and <style> elements we encountered.
190
 
  // This includes those for which we had problem computing summary information.
191
 
  //
192
 
  // Should be called from a thread context that has HTML parser state access.
193
 
  int NumStyles() const { return static_cast<int>(summaries_.size()); }
194
 
 
195
 
  // Returns summary computed for the pos'th style in the document.
196
 
  //
197
 
  // pos must be in [0, NumStyles())
198
 
  //
199
 
  // Should be called from a thread context that has HTML parser state access.
200
 
  const SummaryInfo& GetSummaryForStyle(int pos) const {
201
 
    return summaries_.at(pos);
202
 
  }
203
 
 
204
 
  // Overrides of the filter APIs. You MUST call through to this class's
205
 
  // implementations if you override them.
206
 
  virtual void StartDocumentImpl();
207
 
  virtual void EndDocument();
208
 
  virtual void StartElementImpl(HtmlElement* element);
209
 
  virtual void Characters(HtmlCharactersNode* characters);
210
 
  virtual void EndElementImpl(HtmlElement* element);
211
 
  virtual void RenderDone();
212
 
 
213
 
  virtual RewriteContext* MakeRewriteContext();
214
 
 
215
 
 private:
216
 
  class Context;
217
 
 
218
 
  // Clean out private data.
219
 
  void Clear();
220
 
 
221
 
  // Invokes SummariesDone and, if the debug filter is on, injects a comment
222
 
  // describing what happened with every CSS resource.
223
 
  void ReportSummariesDone();
224
 
 
225
 
  // Starts the asynchronous rewrite process for inline CSS 'text', contained
226
 
  // within the style element 'style'.
227
 
  void StartInlineRewrite(HtmlElement* style, HtmlCharactersNode* text);
228
 
 
229
 
  // Starts the asynchronous rewrite process for external CSS referenced by
230
 
  // attribute 'src' of 'link', whose rel attribute is 'rel'.
231
 
  void StartExternalRewrite(HtmlElement* link, HtmlElement::Attribute* src,
232
 
                            StringPiece rel);
233
 
 
234
 
  // Creates our rewrite context for the given slot and registers it
235
 
  // with the summaries_ vector, filling in the SummaryInfo struct in
236
 
  // a pending state.  The context will still need to have SetupInlineRewrite
237
 
  // or SetupExternalRewrite and InitiateRewrite called on it.
238
 
  // location is used to identify the resource in debug comments.
239
 
  Context* CreateContextAndSummaryInfo(const HtmlElement* element,
240
 
                                       bool external,
241
 
                                       const ResourceSlotPtr& slot,
242
 
                                       const GoogleString& location,
243
 
                                       StringPiece base_for_resources,
244
 
                                       StringPiece rel);
245
 
 
246
 
  ResourceSlot* MakeSlotForInlineCss(HtmlElement* element,
247
 
                                     const StringPiece& content);
248
 
 
249
 
  // Stores all the computed summaries.
250
 
  std::vector<SummaryInfo> summaries_;
251
 
 
252
 
  scoped_ptr<AbstractMutex> progress_lock_;
253
 
  int outstanding_rewrites_;  // guarded by progress_lock_
254
 
  bool saw_end_of_document_;  // guarded by progress_lock_
255
 
  // Lists indexes into summaries_ vector that got canceled due to
256
 
  // disable_further_processing. It's written to in the Rewrite thread,
257
 
  // and then pulled into summaries_ from an HTML thread.
258
 
  std::vector<int> canceled_summaries_;  // guarded by progress_lock_
259
 
 
260
 
  HtmlElement* style_element_;  // The element we are in, or NULL.
261
 
 
262
 
  Variable* num_css_used_for_critical_css_computation_;
263
 
  Variable* num_css_not_used_for_critical_css_computation_;
264
 
 
265
 
  DISALLOW_COPY_AND_ASSIGN(CssSummarizerBase);
266
 
};
267
 
 
268
 
}  // namespace net_instaweb
269
 
 
270
 
#endif  // NET_INSTAWEB_REWRITER_PUBLIC_CSS_SUMMARIZER_BASE_H_