summaryrefslogtreecommitdiffstats
path: root/chrome/browser/blocked_popup_container.cc
blob: d3493140a8584bedb3cab850db06ca1f26efcaa6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// 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.

#include "chrome/browser/blocked_popup_container.h"

#include "chrome/browser/tab_contents/tab_contents.h"
#include "gfx/rect.h"

// static
const size_t BlockedPopupContainer::kImpossibleNumberOfPopups = 30;

struct BlockedPopupContainer::BlockedPopup {
  BlockedPopup(TabContents* tab_contents,
               const gfx::Rect& bounds)
      : tab_contents(tab_contents), bounds(bounds) {
  }

  TabContents* tab_contents;
  gfx::Rect bounds;
};

BlockedPopupContainer::BlockedPopupContainer(TabContents* owner)
    : owner_(owner) {
}

void BlockedPopupContainer::AddTabContents(TabContents* tab_contents,
                                           const gfx::Rect& bounds) {
  if (blocked_popups_.size() == (kImpossibleNumberOfPopups - 1)) {
    delete tab_contents;
    LOG(INFO) << "Warning: Renderer is sending more popups to us than should "
        "be possible. Renderer compromised?";
    return;
  }

  blocked_popups_.push_back(BlockedPopup(tab_contents, bounds));
  tab_contents->set_delegate(this);
  if (blocked_popups_.size() == 1)
    owner_->PopupNotificationVisibilityChanged(true);
}

void BlockedPopupContainer::LaunchPopupForContents(TabContents* tab_contents) {
  // Open the popup.
  for (BlockedPopups::iterator i(blocked_popups_.begin());
       i != blocked_popups_.end(); ++i) {
    if (i->tab_contents == tab_contents) {
      tab_contents->set_delegate(NULL);
      owner_->AddNewContents(tab_contents, NEW_POPUP, i->bounds, true);
      blocked_popups_.erase(i);
      break;
    }
  }

  if (blocked_popups_.empty())
    Destroy();
}

size_t BlockedPopupContainer::GetBlockedPopupCount() const {
  return blocked_popups_.size();
}

void BlockedPopupContainer::GetBlockedContents(
    BlockedContents* blocked_contents) const {
  DCHECK(blocked_contents);
  for (BlockedPopups::const_iterator i(blocked_popups_.begin());
       i != blocked_popups_.end(); ++i)
    blocked_contents->push_back(i->tab_contents);
}

void BlockedPopupContainer::Destroy() {
  for (BlockedPopups::iterator i(blocked_popups_.begin());
       i != blocked_popups_.end(); ++i) {
    TabContents* tab_contents = i->tab_contents;
    tab_contents->set_delegate(NULL);
    delete tab_contents;
  }
  blocked_popups_.clear();
  owner_->WillCloseBlockedPopupContainer(this);
  delete this;
}

// Overridden from TabContentsDelegate:
void BlockedPopupContainer::OpenURLFromTab(TabContents* source,
                                           const GURL& url,
                                           const GURL& referrer,
                                           WindowOpenDisposition disposition,
                                           PageTransition::Type transition) {
  owner_->OpenURL(url, referrer, disposition, transition);
}

void BlockedPopupContainer::AddNewContents(TabContents* source,
                                           TabContents* new_contents,
                                           WindowOpenDisposition disposition,
                                           const gfx::Rect& initial_position,
                                           bool user_gesture) {
  owner_->AddNewContents(new_contents, disposition, initial_position,
                         user_gesture);
}

void BlockedPopupContainer::CloseContents(TabContents* source) {
  for (BlockedPopups::iterator i(blocked_popups_.begin());
       i != blocked_popups_.end(); ++i) {
    TabContents* tab_contents = i->tab_contents;
    if (tab_contents == source) {
      tab_contents->set_delegate(NULL);
      blocked_popups_.erase(i);
      delete tab_contents;
      break;
    }
  }
}

void BlockedPopupContainer::MoveContents(TabContents* source,
                                         const gfx::Rect& new_bounds) {
  for (BlockedPopups::iterator i(blocked_popups_.begin());
       i != blocked_popups_.end(); ++i) {
    if (i->tab_contents == source) {
      i->bounds = new_bounds;
      break;
    }
  }
}

bool BlockedPopupContainer::IsPopup(const TabContents* source) const {
  return true;
}

TabContents* BlockedPopupContainer::GetConstrainingContents(
    TabContents* source) {
  return owner_;
}