| /* |
| * Copyright 2013 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: jmaessen@google.com (Jan-Willem Maessen) |
| |
| #ifndef NET_INSTAWEB_REWRITER_PUBLIC_CRITICAL_CSS_BEACON_FILTER_H_ |
| #define NET_INSTAWEB_REWRITER_PUBLIC_CRITICAL_CSS_BEACON_FILTER_H_ |
| |
| #include "net/instaweb/rewriter/public/css_summarizer_base.h" |
| #include "net/instaweb/rewriter/public/rewrite_driver.h" |
| #include "net/instaweb/rewriter/public/rewrite_options.h" |
| #include "pagespeed/kernel/base/basictypes.h" |
| #include "pagespeed/kernel/base/string.h" |
| #include "pagespeed/kernel/base/string_util.h" |
| #include "pagespeed/kernel/http/semantic_type.h" |
| |
| namespace Css { |
| |
| class Ruleset; |
| class Stylesheet; |
| |
| } // namespace Css |
| |
| namespace net_instaweb { |
| |
| struct BeaconMetadata; |
| class HtmlElement; |
| class Statistics; |
| class Variable; |
| |
| // Figure out the set of CSS selectors referenced from a page, saving those |
| // selectors in an OutputResource for each CSS <style> or <link> on the page. |
| // Based on that set of candidate critical selectors, inject javascript for |
| // detecting critical above the fold css selectors after the page has loaded. |
| // Assumes CSS @imports have been flattened first. |
| class CriticalCssBeaconFilter : public CssSummarizerBase { |
| public: |
| static const char kInitializePageSpeedJs[]; |
| |
| // Statistics: |
| static const char kCriticalCssBeaconAddedCount[]; |
| static const char kCriticalCssNoBeaconDueToMissingData[]; |
| static const char kCriticalCssSkippedDueToCharset[]; |
| |
| explicit CriticalCssBeaconFilter(RewriteDriver* driver); |
| virtual ~CriticalCssBeaconFilter(); |
| |
| static void InitStats(Statistics* statistics); |
| |
| virtual const char* Name() const { return "CriticalCssBeacon"; } |
| virtual const char* id() const { return "cb"; } |
| |
| // This filter needs access to all critical selectors (even those from |
| // unauthorized domains) in order to let the clients use them while |
| // detecting critical selectors that can be subsequently beaconed back |
| // to the server and eventually inlined into the HTML. |
| virtual RewriteDriver::InlineAuthorizationPolicy AllowUnauthorizedDomain() |
| const { |
| return driver()->options()->HasInlineUnauthorizedResourceType( |
| semantic_type::kStylesheet) ? |
| RewriteDriver::kInlineUnauthorizedResources : |
| RewriteDriver::kInlineOnlyAuthorizedResources; |
| } |
| |
| // Selectors are inlined into javascript. |
| virtual bool IntendedForInlining() const { return true; } |
| |
| protected: |
| virtual bool MustSummarize(HtmlElement* element) const; |
| virtual void Summarize(Css::Stylesheet* stylesheet, |
| GoogleString* out) const; |
| virtual void SummariesDone(); |
| |
| virtual void DetermineEnabled(GoogleString* disabled_reason); |
| |
| private: |
| static void FindSelectorsFromRuleset(const Css::Ruleset& ruleset, |
| StringSet* selectors); |
| // The following adds the selectors to the given StringSet. |
| static void FindSelectorsFromStylesheet(const Css::Stylesheet& css, |
| StringSet* selectors); |
| |
| // Append the selectors initialization JavaScript. |
| void AppendSelectorsInitJs(GoogleString* script, const StringSet& selectors); |
| |
| // Append the beaconing initialization JavaScript. |
| void AppendBeaconInitJs(const BeaconMetadata& metadata, GoogleString* script); |
| |
| // The total number of times the beacon is added to a page. |
| Variable* critical_css_beacon_added_count_; |
| // The number of times we abandon beacon insertion due to missing CSS data (it |
| // was still being fetched / rewritten). |
| Variable* critical_css_no_beacon_due_to_missing_data_; |
| // The number of CSS files we ignore due to charset incompatibility. |
| // Should these block critical CSS insertion? |
| Variable* critical_css_skipped_due_to_charset_; |
| |
| DISALLOW_COPY_AND_ASSIGN(CriticalCssBeaconFilter); |
| }; |
| |
| } // namespace net_instaweb |
| |
| #endif // NET_INSTAWEB_REWRITER_PUBLIC_CRITICAL_CSS_BEACON_FILTER_H_ |