<commit_before>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/renderer/print_web_view_helper.h"

#include "app/l10n_util.h"
#include "base/logging.h"
#include "chrome/common/render_messages.h"
#include "chrome/renderer/render_view.h"
#include "gfx/codec/jpeg_codec.h"
#include "grit/generated_resources.h"
#include "printing/units.h"
#include "third_party/WebKit/WebKit/chromium/public/WebConsoleMessage.h"
#include "third_party/WebKit/WebKit/chromium/public/WebFrame.h"
#include "third_party/WebKit/WebKit/chromium/public/WebRect.h"
#include "third_party/WebKit/WebKit/chromium/public/WebScreenInfo.h"
#include "third_party/WebKit/WebKit/chromium/public/WebSize.h"
#include "third_party/WebKit/WebKit/chromium/public/WebURLRequest.h"
#include "webkit/glue/webkit_glue.h"

using printing::ConvertPixelsToPoint;
using printing::ConvertPixelsToPointDouble;
using printing::ConvertUnit;
using printing::ConvertUnitDouble;
using WebKit::WebConsoleMessage;
using WebKit::WebFrame;
using WebKit::WebRect;
using WebKit::WebSize;
using WebKit::WebScreenInfo;
using WebKit::WebString;
using WebKit::WebURLRequest;
using WebKit::WebView;

PrepareFrameAndViewForPrint::PrepareFrameAndViewForPrint(
    const ViewMsg_Print_Params& print_params,
    WebFrame* frame,
    WebView* web_view)
        : frame_(frame), web_view_(web_view), expected_pages_count_(0),
          use_browser_overlays_(true) {
  int dpi = static_cast<int>(print_params.dpi);
#if defined(OS_MACOSX)
  // On the Mac, the printable area is in points, don't do any scaling based
  // on dpi.
  dpi = printing::kPointsPerInch;
#endif  // defined(OS_MACOSX)
  print_canvas_size_.set_width(
      ConvertUnit(print_params.printable_size.width(), dpi,
                  print_params.desired_dpi));

  print_canvas_size_.set_height(
      ConvertUnit(print_params.printable_size.height(), dpi,
                  print_params.desired_dpi));

  // Layout page according to printer page size. Since WebKit shrinks the
  // size of the page automatically (from 125% to 200%) we trick it to
  // think the page is 125% larger so the size of the page is correct for
  // minimum (default) scaling.
  // This is important for sites that try to fill the page.
  gfx::Size print_layout_size(print_canvas_size_);
  print_layout_size.set_height(static_cast<int>(
      static_cast<double>(print_layout_size.height()) * 1.25));

  prev_view_size_ = web_view->size();

  web_view->resize(print_layout_size);

  expected_pages_count_ = frame->printBegin(
      print_canvas_size_, static_cast<int>(print_params.dpi),
      &use_browser_overlays_);
}

PrepareFrameAndViewForPrint::~PrepareFrameAndViewForPrint() {
  frame_->printEnd();
  web_view_->resize(prev_view_size_);
}


PrintWebViewHelper::PrintWebViewHelper(RenderView* render_view)
    : render_view_(render_view),
      print_web_view_(NULL),
      user_cancelled_scripted_print_count_(0) {}

PrintWebViewHelper::~PrintWebViewHelper() {}

#if defined(OS_MACOSX) || defined(OS_WIN)
void PrintWebViewHelper::Print(WebFrame* frame, bool script_initiated) {
  const int kMinSecondsToIgnoreJavascriptInitiatedPrint = 2;
  const int kMaxSecondsToIgnoreJavascriptInitiatedPrint = 2 * 60;  // 2 Minutes.

  // If still not finished with earlier print request simply ignore.
  if (IsPrinting())
    return;

  // Check if there is script repeatedly trying to print and ignore it if too
  // frequent.  We use exponential wait time so for a page that calls print() in
  // a loop the user will need to cancel the print dialog after 2 seconds, 4
  // seconds, 8, ... up to the maximum of 2 minutes.
  // This gives the user time to navigate from the page.
  if (script_initiated && (user_cancelled_scripted_print_count_ > 0)) {
    base::TimeDelta diff = base::Time::Now() - last_cancelled_script_print_;
    int min_wait_seconds = std::min(
        kMinSecondsToIgnoreJavascriptInitiatedPrint <<
            (user_cancelled_scripted_print_count_ - 1),
        kMaxSecondsToIgnoreJavascriptInitiatedPrint);
    if (diff.InSeconds() < min_wait_seconds) {
      WebString message(WebString::fromUTF8(
          "Ignoring too frequent calls to print()."));
      frame->addMessageToConsole(WebConsoleMessage(
          WebConsoleMessage::LevelWarning,
          message));
      return;
    }
  }

  // Retrieve the default print settings to calculate the expected number of
  // pages.
  ViewMsg_Print_Params default_settings;
  bool print_cancelled = false;

  IPC::SyncMessage* msg =
      new ViewHostMsg_GetDefaultPrintSettings(routing_id(), &default_settings);
  if (Send(msg)) {
    msg = NULL;
    // Check if the printer returned any settings, if the settings is empty, we
    // can safely assume there are no printer drivers configured. So we safely
    // terminate.
    if (default_settings.IsEmpty()) {
      // TODO: Create an async alert (http://crbug.com/14918).
      render_view_->runModalAlertDialog(frame,
          l10n_util::GetStringUTF16(IDS_DEFAULT_PRINTER_NOT_FOUND_WARNING));
      return;
    }

    UpdatePrintableSizeInPrintParameters(frame, &default_settings);

    // Continue only if the settings are valid.
    if (default_settings.dpi && default_settings.document_cookie) {
      int expected_pages_count = 0;
      bool use_browser_overlays = true;

      // Prepare once to calculate the estimated page count.  This must be in
      // a scope for itself (see comments on PrepareFrameAndViewForPrint).
      {
        PrepareFrameAndViewForPrint prep_frame_view(default_settings,
                                                    frame,
                                                    frame->view());
        expected_pages_count = prep_frame_view.GetExpectedPageCount();
        if (expected_pages_count)
          use_browser_overlays = prep_frame_view.ShouldUseBrowserOverlays();
      }

      // Some full screen plugins can say they don't want to print.
      if (expected_pages_count) {
        // Ask the browser to show UI to retrieve the final print settings.
        ViewMsg_PrintPages_Params print_settings;

        ViewHostMsg_ScriptedPrint_Params params;

        // The routing id is sent across as it is needed to look up the
        // corresponding RenderViewHost instance to signal and reset the
        // pump messages event.
        params.routing_id = routing_id();
        // host_window_ may be NULL at this point if the current window is a
        // popup and the print() command has been issued from the parent. The
        // receiver of this message has to deal with this.
        params.host_window_id = render_view_->host_window();
        params.cookie = default_settings.document_cookie;
        params.has_selection = frame->hasSelection();
        params.expected_pages_count = expected_pages_count;
        params.use_overlays = use_browser_overlays;

        msg = new ViewHostMsg_ScriptedPrint(routing_id(), params,
                                            &print_settings);
        msg->EnableMessagePumping();
        if (Send(msg)) {
          msg = NULL;

          UpdatePrintableSizeInPrintParameters(frame, &print_settings.params);

          // If the settings are invalid, early quit.
          if (print_settings.params.dpi &&
              print_settings.params.document_cookie) {
            if (print_settings.params.selection_only) {
              CopyAndPrint(print_settings, frame);
            } else {
              // TODO: Always copy before printing.
              PrintPages(print_settings, frame);
            }

            // Reset cancel counter on first successful print.
            user_cancelled_scripted_print_count_ = 0;<commit_msg>Fix a Chrome renderer crash which occurs on closing the print dialog right after it was opened. This is because of attempting to calculate the printable area while the settings are invalid leading to a divide by zero crash.<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/renderer/print_web_view_helper.h"

#include "app/l10n_util.h"
#include "base/logging.h"
#include "chrome/common/render_messages.h"
#include "chrome/renderer/render_view.h"
#include "gfx/codec/jpeg_codec.h"
#include "grit/generated_resources.h"
#include "printing/units.h"
#include "third_party/WebKit/WebKit/chromium/public/WebConsoleMessage.h"
#include "third_party/WebKit/WebKit/chromium/public/WebFrame.h"
#include "third_party/WebKit/WebKit/chromium/public/WebRect.h"
#include "third_party/WebKit/WebKit/chromium/public/WebScreenInfo.h"
#include "third_party/WebKit/WebKit/chromium/public/WebSize.h"
#include "third_party/WebKit/WebKit/chromium/public/WebURLRequest.h"
#include "webkit/glue/webkit_glue.h"

using printing::ConvertPixelsToPoint;
using printing::ConvertPixelsToPointDouble;
using printing::ConvertUnit;
using printing::ConvertUnitDouble;
using WebKit::WebConsoleMessage;
using WebKit::WebFrame;
using WebKit::WebRect;
using WebKit::WebSize;
using WebKit::WebScreenInfo;
using WebKit::WebString;
using WebKit::WebURLRequest;
using WebKit::WebView;

PrepareFrameAndViewForPrint::PrepareFrameAndViewForPrint(
    const ViewMsg_Print_Params& print_params,
    WebFrame* frame,
    WebView* web_view)
        : frame_(frame), web_view_(web_view), expected_pages_count_(0),
          use_browser_overlays_(true) {
  int dpi = static_cast<int>(print_params.dpi);
#if defined(OS_MACOSX)
  // On the Mac, the printable area is in points, don't do any scaling based
  // on dpi.
  dpi = printing::kPointsPerInch;
#endif  // defined(OS_MACOSX)
  print_canvas_size_.set_width(
      ConvertUnit(print_params.printable_size.width(), dpi,
                  print_params.desired_dpi));

  print_canvas_size_.set_height(
      ConvertUnit(print_params.printable_size.height(), dpi,
                  print_params.desired_dpi));

  // Layout page according to printer page size. Since WebKit shrinks the
  // size of the page automatically (from 125% to 200%) we trick it to
  // think the page is 125% larger so the size of the page is correct for
  // minimum (default) scaling.
  // This is important for sites that try to fill the page.
  gfx::Size print_layout_size(print_canvas_size_);
  print_layout_size.set_height(static_cast<int>(
      static_cast<double>(print_layout_size.height()) * 1.25));

  prev_view_size_ = web_view->size();

  web_view->resize(print_layout_size);

  expected_pages_count_ = frame->printBegin(
      print_canvas_size_, static_cast<int>(print_params.dpi),
      &use_browser_overlays_);
}

PrepareFrameAndViewForPrint::~PrepareFrameAndViewForPrint() {
  frame_->printEnd();
  web_view_->resize(prev_view_size_);
}


PrintWebViewHelper::PrintWebViewHelper(RenderView* render_view)
    : render_view_(render_view),
      print_web_view_(NULL),
      user_cancelled_scripted_print_count_(0) {}

PrintWebViewHelper::~PrintWebViewHelper() {}

#if defined(OS_MACOSX) || defined(OS_WIN)
void PrintWebViewHelper::Print(WebFrame* frame, bool script_initiated) {
  const int kMinSecondsToIgnoreJavascriptInitiatedPrint = 2;
  const int kMaxSecondsToIgnoreJavascriptInitiatedPrint = 2 * 60;  // 2 Minutes.

  // If still not finished with earlier print request simply ignore.
  if (IsPrinting())
    return;

  // Check if there is script repeatedly trying to print and ignore it if too
  // frequent.  We use exponential wait time so for a page that calls print() in
  // a loop the user will need to cancel the print dialog after 2 seconds, 4
  // seconds, 8, ... up to the maximum of 2 minutes.
  // This gives the user time to navigate from the page.
  if (script_initiated && (user_cancelled_scripted_print_count_ > 0)) {
    base::TimeDelta diff = base::Time::Now() - last_cancelled_script_print_;
    int min_wait_seconds = std::min(
        kMinSecondsToIgnoreJavascriptInitiatedPrint <<
            (user_cancelled_scripted_print_count_ - 1),
        kMaxSecondsToIgnoreJavascriptInitiatedPrint);
    if (diff.InSeconds() < min_wait_seconds) {
      WebString message(WebString::fromUTF8(
          "Ignoring too frequent calls to print()."));
      frame->addMessageToConsole(WebConsoleMessage(
          WebConsoleMessage::LevelWarning,
          message));
      return;
    }
  }

  // Retrieve the default print settings to calculate the expected number of
  // pages.
  ViewMsg_Print_Params default_settings;
  bool print_cancelled = false;

  IPC::SyncMessage* msg =
      new ViewHostMsg_GetDefaultPrintSettings(routing_id(), &default_settings);
  if (Send(msg)) {
    msg = NULL;
    // Check if the printer returned any settings, if the settings is empty, we
    // can safely assume there are no printer drivers configured. So we safely
    // terminate.
    if (default_settings.IsEmpty()) {
      // TODO: Create an async alert (http://crbug.com/14918).
      render_view_->runModalAlertDialog(frame,
          l10n_util::GetStringUTF16(IDS_DEFAULT_PRINTER_NOT_FOUND_WARNING));
      return;
    }

    // Continue only if the settings are valid.
    if (default_settings.dpi && default_settings.document_cookie) {
      UpdatePrintableSizeInPrintParameters(frame, &default_settings);
      int expected_pages_count = 0;
      bool use_browser_overlays = true;

      // Prepare once to calculate the estimated page count.  This must be in
      // a scope for itself (see comments on PrepareFrameAndViewForPrint).
      {
        PrepareFrameAndViewForPrint prep_frame_view(default_settings,
                                                    frame,
                                                    frame->view());
        expected_pages_count = prep_frame_view.GetExpectedPageCount();
        if (expected_pages_count)
          use_browser_overlays = prep_frame_view.ShouldUseBrowserOverlays();
      }

      // Some full screen plugins can say they don't want to print.
      if (expected_pages_count) {
        // Ask the browser to show UI to retrieve the final print settings.
        ViewMsg_PrintPages_Params print_settings;

        ViewHostMsg_ScriptedPrint_Params params;

        // The routing id is sent across as it is needed to look up the
        // corresponding RenderViewHost instance to signal and reset the
        // pump messages event.
        params.routing_id = routing_id();
        // host_window_ may be NULL at this point if the current window is a
        // popup and the print() command has been issued from the parent. The
        // receiver of this message has to deal with this.
        params.host_window_id = render_view_->host_window();
        params.cookie = default_settings.document_cookie;
        params.has_selection = frame->hasSelection();
        params.expected_pages_count = expected_pages_count;
        params.use_overlays = use_browser_overlays;

        msg = new ViewHostMsg_ScriptedPrint(routing_id(), params,
                                            &print_settings);
        msg->EnableMessagePumping();
        if (Send(msg)) {
          msg = NULL;

          // If the settings are invalid, early quit.
          if (print_settings.params.dpi &&
              print_settings.params.document_cookie) {
            UpdatePrintableSizeInPrintParameters(frame, &print_settings.params);
            if (print_settings.params.selection_only) {
              CopyAndPrint(print_settings, frame);
            } else {
              // TODO: Always copy before printing.
              PrintPages(print_settings, frame);
            }

            // Reset cancel counter on first successful print.
            user_cancelled_scripted_print_count_ = 0;
{'fraction_non_alphanumeric': 0.08766810454199442, 'fraction_numerical': 0.005455468155290535, 'mean_word_length': 3.3132694938440492, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 12, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4139262', 'n_tokens_mistral': 4650, 'n_tokens_neox': 4510, 'n_words': 1199}