<commit_before>// Copyright (c) 2010 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.

#import "chrome/browser/cocoa/page_info_bubble_controller.h"

#include "app/l10n_util.h"
#include "app/l10n_util_mac.h"
#include "base/sys_string_conversions.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/cert_store.h"
#include "chrome/browser/certificate_viewer.h"
#import "chrome/browser/cocoa/browser_window_controller.h"
#import "chrome/browser/cocoa/hyperlink_button_cell.h"
#import "chrome/browser/cocoa/info_bubble_view.h"
#import "chrome/browser/cocoa/info_bubble_window.h"
#import "chrome/browser/cocoa/location_bar/location_bar_view_mac.h"
#include "chrome/browser/profile.h"
#include "grit/generated_resources.h"
#include "grit/locale_settings.h"
#include "net/base/cert_status_flags.h"
#include "net/base/x509_certificate.h"
#import "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h"

@interface PageInfoBubbleController (Private)
- (PageInfoModel*)model;
- (NSButton*)certificateButtonWithFrame:(NSRect)frame;
- (void)configureTextFieldAsLabel:(NSTextField*)textField;
- (CGFloat)addHeadlineViewForInfo:(const PageInfoModel::SectionInfo&)info
                       toSubviews:(NSMutableArray*)subviews
                          atPoint:(NSPoint)point;
- (CGFloat)addDescriptionViewForInfo:(const PageInfoModel::SectionInfo&)info
                          toSubviews:(NSMutableArray*)subviews
                             atPoint:(NSPoint)point;
- (CGFloat)addCertificateButtonToSubviews:(NSMutableArray*)subviews
                                 atOffset:(CGFloat)offset;
- (void)addImageViewForInfo:(const PageInfoModel::SectionInfo&)info
                 toSubviews:(NSMutableArray*)subviews
                   atOffset:(CGFloat)offset;
- (CGFloat)addHelpButtonToSubviews:(NSMutableArray*)subviews
                          atOffset:(CGFloat)offset;
- (CGFloat)addSeparatorToSubviews:(NSMutableArray*)subviews
                         atOffset:(CGFloat)offset;
- (NSPoint)anchorPointForWindowWithHeight:(CGFloat)bubbleHeight
                             parentWindow:(NSWindow*)parent;
@end

// This simple NSView subclass is used as the single subview of the page info
// bubble's window's contentView. Drawing is flipped so that layout of the
// sections is easier. Apple recommends flipping the coordinate origin when
// doing a lot of text layout because it's more natural.
@interface PageInfoContentView : NSView {
}
@end
@implementation PageInfoContentView
- (BOOL)isFlipped {
  return YES;
}
@end

namespace {

// The width of the window, in view coordinates. The height will be determined
// by the content.
const NSInteger kWindowWidth = 380;

// Spacing in between sections.
const NSInteger kVerticalSpacing = 10;

// Padding along on the X-axis between the window frame and content.
const NSInteger kFramePadding = 20;

// Spacing between the optional headline and description text views.
const NSInteger kHeadlineSpacing = 2;

// Spacing between the image and the text.
const NSInteger kImageSpacing = 10;

// Square size of the image.
const CGFloat kImageSize = 30;

// The X position of the text fields. Variants for with and without an image.
const CGFloat kTextXPositionNoImage = kFramePadding;
const CGFloat kTextXPosition = kTextXPositionNoImage + kImageSize +
    kImageSpacing;

// Width of the text fields.
const CGFloat kTextWidth = kWindowWidth - (kImageSize + kImageSpacing +
    kFramePadding * 2);


// Bridge that listens for change notifications from the model.
class PageInfoModelBubbleBridge : public PageInfoModel::PageInfoModelObserver {
 public:
  PageInfoModelBubbleBridge() : controller_(nil) {}

  // PageInfoModelObserver implementation.
  virtual void ModelChanged() {
    // Delay performing layout by a second so that all the animations from
    // InfoBubbleWindow and origin updates from BaseBubbleController finish, so
    // that we don't all race trying to change the frame's origin.
    [controller_ performSelector:@selector(performLayout)
                      withObject:nil
                      afterDelay:1.0];
  }

  // Sets the controller.
  void set_controller(PageInfoBubbleController* controller) {
    controller_ = controller;
  }

 private:
  PageInfoBubbleController* controller_;  // weak
};

}  // namespace

namespace browser {

void ShowPageInfoBubble(gfx::NativeWindow parent,
                        Profile* profile,
                        const GURL& url,
                        const NavigationEntry::SSLStatus& ssl,
                        bool show_history) {
  PageInfoModelBubbleBridge* bridge = new PageInfoModelBubbleBridge();
  PageInfoModel* model =
      new PageInfoModel(profile, url, ssl, show_history, bridge);
  PageInfoBubbleController* controller =<commit_msg>Schedule layout of the Page Info Bubble using RunnableMethod rather than |-performSelector:...|.<commit_after>// Copyright (c) 2010 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.

#import "chrome/browser/cocoa/page_info_bubble_controller.h"

#include "app/l10n_util.h"
#include "app/l10n_util_mac.h"
#include "base/message_loop.h"
#include "base/sys_string_conversions.h"
#include "base/task.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/cert_store.h"
#include "chrome/browser/certificate_viewer.h"
#import "chrome/browser/cocoa/browser_window_controller.h"
#import "chrome/browser/cocoa/hyperlink_button_cell.h"
#import "chrome/browser/cocoa/info_bubble_view.h"
#import "chrome/browser/cocoa/info_bubble_window.h"
#import "chrome/browser/cocoa/location_bar/location_bar_view_mac.h"
#include "chrome/browser/profile.h"
#include "grit/generated_resources.h"
#include "grit/locale_settings.h"
#include "net/base/cert_status_flags.h"
#include "net/base/x509_certificate.h"
#import "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h"

@interface PageInfoBubbleController (Private)
- (PageInfoModel*)model;
- (NSButton*)certificateButtonWithFrame:(NSRect)frame;
- (void)configureTextFieldAsLabel:(NSTextField*)textField;
- (CGFloat)addHeadlineViewForInfo:(const PageInfoModel::SectionInfo&)info
                       toSubviews:(NSMutableArray*)subviews
                          atPoint:(NSPoint)point;
- (CGFloat)addDescriptionViewForInfo:(const PageInfoModel::SectionInfo&)info
                          toSubviews:(NSMutableArray*)subviews
                             atPoint:(NSPoint)point;
- (CGFloat)addCertificateButtonToSubviews:(NSMutableArray*)subviews
                                 atOffset:(CGFloat)offset;
- (void)addImageViewForInfo:(const PageInfoModel::SectionInfo&)info
                 toSubviews:(NSMutableArray*)subviews
                   atOffset:(CGFloat)offset;
- (CGFloat)addHelpButtonToSubviews:(NSMutableArray*)subviews
                          atOffset:(CGFloat)offset;
- (CGFloat)addSeparatorToSubviews:(NSMutableArray*)subviews
                         atOffset:(CGFloat)offset;
- (NSPoint)anchorPointForWindowWithHeight:(CGFloat)bubbleHeight
                             parentWindow:(NSWindow*)parent;
@end

// This simple NSView subclass is used as the single subview of the page info
// bubble's window's contentView. Drawing is flipped so that layout of the
// sections is easier. Apple recommends flipping the coordinate origin when
// doing a lot of text layout because it's more natural.
@interface PageInfoContentView : NSView {
}
@end
@implementation PageInfoContentView
- (BOOL)isFlipped {
  return YES;
}
@end

namespace {

// The width of the window, in view coordinates. The height will be determined
// by the content.
const NSInteger kWindowWidth = 380;

// Spacing in between sections.
const NSInteger kVerticalSpacing = 10;

// Padding along on the X-axis between the window frame and content.
const NSInteger kFramePadding = 20;

// Spacing between the optional headline and description text views.
const NSInteger kHeadlineSpacing = 2;

// Spacing between the image and the text.
const NSInteger kImageSpacing = 10;

// Square size of the image.
const CGFloat kImageSize = 30;

// The X position of the text fields. Variants for with and without an image.
const CGFloat kTextXPositionNoImage = kFramePadding;
const CGFloat kTextXPosition = kTextXPositionNoImage + kImageSize +
    kImageSpacing;

// Width of the text fields.
const CGFloat kTextWidth = kWindowWidth - (kImageSize + kImageSpacing +
    kFramePadding * 2);

// Bridge that listens for change notifications from the model.
class PageInfoModelBubbleBridge : public PageInfoModel::PageInfoModelObserver {
 public:
  PageInfoModelBubbleBridge()
      : controller_(nil),
        ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)) {
  }

  // PageInfoModelObserver implementation.
  virtual void ModelChanged() {
    // Check to see if a layout has already been scheduled.
    if (!task_factory_.empty())
      return;

    // Delay performing layout by a second so that all the animations from
    // InfoBubbleWindow and origin updates from BaseBubbleController finish, so
    // that we don't all race trying to change the frame's origin.
    //
    // Using ScopedRunnableMethodFactory is superior here to |-performSelector:|
    // because it will not retain its target; if the child outlives its parent,
    // zombies get left behind (http://crbug.com/59619). This will also cancel
    // the scheduled Tasks if the controller (and thus this bridge) get
    // destroyed before the message can be delivered.
    MessageLoop::current()->PostDelayedTask(FROM_HERE,
        task_factory_.NewRunnableMethod(
            &PageInfoModelBubbleBridge::PerformLayout),
        1000 /* milliseconds */);
  }

  // Sets the controller.
  void set_controller(PageInfoBubbleController* controller) {
    controller_ = controller;
  }

 private:
  void PerformLayout() {
    [controller_ performLayout];
  }

  PageInfoBubbleController* controller_;  // weak

  // Factory that vends RunnableMethod tasks for scheduling layout.
  ScopedRunnableMethodFactory<PageInfoModelBubbleBridge> task_factory_;
};

}  // namespace

namespace browser {

void ShowPageInfoBubble(gfx::NativeWindow parent,
                        Profile* profile,
                        const GURL& url,
                        const NavigationEntry::SSLStatus& ssl,
                        bool show_history) {
  PageInfoModelBubbleBridge* bridge = new PageInfoModelBubbleBridge();
  PageInfoModel* model =
      new PageInfoModel(profile, url, ssl, show_history, bridge);
  PageInfoBubbleController* controller =
{'fraction_non_alphanumeric': 0.08711908767994017, 'fraction_numerical': 0.005515049541970462, 'mean_word_length': 3.6822757111597375, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4327088', 'n_tokens_mistral': 3179, 'n_tokens_neox': 3013, 'n_words': 809}