text: /*
   * 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.
   */
  
  // Authors: mmohabey@google.com (Megha Mohabey)
  //          rahulbansal@google.com (Rahul Bansal)
  
  #ifndef NET_INSTAWEB_REWRITER_PUBLIC_CACHE_HTML_FILTER_H_
  #define NET_INSTAWEB_REWRITER_PUBLIC_CACHE_HTML_FILTER_H_
  
  #include <vector>
  
  #include "net/instaweb/rewriter/cache_html_info.pb.h"
  #include "net/instaweb/rewriter/public/blink_util.h"
  #include "net/instaweb/util/public/property_cache.h"
  #include "pagespeed/kernel/base/basictypes.h"
  #include "pagespeed/kernel/base/json.h"
  #include "pagespeed/kernel/base/string.h"
  #include "pagespeed/kernel/base/string_util.h"
  #include "pagespeed/kernel/base/string_writer.h"
  #include "pagespeed/kernel/html/html_writer_filter.h"
  
  namespace net_instaweb {
  
  class HtmlElement;
  class RewriteDriver;
  class RewriteOptions;
  
  // This class extracts the non cacheable panels and sends it to the client.
  // TODO(mmohabey): Integrate with SplitFilter and send non critical JSON too.
  class CacheHtmlFilter : public HtmlWriterFilter {
   public:
    explicit CacheHtmlFilter(RewriteDriver* rewrite_driver);
    virtual ~CacheHtmlFilter();
  
    virtual void StartDocument();
    virtual void StartElement(HtmlElement* element);
    virtual void EndElement(HtmlElement* element);
    virtual void EndDocument();
    void WriteString(StringPiece str);
    virtual void Flush();
    virtual const char* Name() const { return "CacheHtmlFilter"; }
  
   private:
    void SendCookies();
    void SendNonCacheableObject(const Json::Value& json);
    // Produces a custom xpath relative to the body or relative to the nearest
    // ancestor with an id (if there is one). Xpath comprises of the tag name
    // and the id (if it exists) or the position of the elements.
    GoogleString GetXpathOfCurrentElement(HtmlElement* element);
  
    RewriteDriver* rewrite_driver_;  // We do not own this.
    const RewriteOptions* rewrite_options_;  // We do not own this.
    AttributesToNonCacheableValuesMap attribute_non_cacheable_values_map_;
    std::vector<int> panel_number_num_instances_;
    GoogleString buffer_;
    StringWriter string_writer_;
    const HtmlElement* current_non_cacheable_element_;  // We do not own this.
    GoogleString current_panel_id_;
    const PropertyCache::Cohort* cohort_;  // We do not own this.
    CacheHtmlInfo cache_html_info_;
    bool abort_filter_;
    std::vector<int> num_children_stack_;
  
    DISALLOW_COPY_AND_ASSIGN(CacheHtmlFilter);
  };
  
  }  // namespace net_instaweb
  
  #endif  // NET_INSTAWEB_REWRITER_PUBLIC_CACHE_HTML_FILTER_H_
  