add indicator of blocked popup and a popdown menu to quickly unblock sites

This commit is contained in:
pinkerton%netscape.com 2003-05-14 03:45:06 +00:00
parent 1f45d1ea47
commit 9371f49703
14 changed files with 311 additions and 16 deletions

View File

@ -841,6 +841,7 @@
3003B8A4044514B600B85BF3,
3003B8A5044514B600B85BF3,
3003B8AD044514E300B85BF3,
3FAD95550461E43700A80005,
);
isa = PBXResourcesBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
@ -1390,6 +1391,24 @@
settings = {
};
};
3F8D26DE0471ED0F00A80005 = {
fileRef = 3FAD95540461E43700A80005;
isa = PBXBuildFile;
settings = {
};
};
3FAD95540461E43700A80005 = {
isa = PBXFileReference;
name = "popup-blocked.png";
path = "resources/images/chrome/popup-blocked.png";
refType = 2;
};
3FAD95550461E43700A80005 = {
fileRef = 3FAD95540461E43700A80005;
isa = PBXBuildFile;
settings = {
};
};
//3F0
//3F1
//3F2
@ -1921,6 +1940,7 @@
F557149E023B46BF010001CA,
F540BD1A029ED15301026D5D,
F540BD1C029ED17901026D5D,
3FAD95540461E43700A80005,
F5A112C902DF270F01026D5D,
F55B6BF402EF1F7E01026D5D,
F583E3B503B8204901A80166,
@ -7930,6 +7950,7 @@
3003B8A9044514B600B85BF3,
3003B8AA044514B600B85BF3,
3003B8AE044514E300B85BF3,
3F8D26DE0471ED0F00A80005,
);
isa = PBXResourcesBuildPhase;
runOnlyForDeploymentPostprocessing = 0;

View File

@ -90,6 +90,7 @@
closeCurrentTab = id;
closeOtherTabs = id;
closeSendersTab = id;
configurePopupBlocking = id;
copyImage = id;
copyImageLocation = id;
copyLinkLocation = id;
@ -127,6 +128,8 @@
stop = id;
toggleBookmarkManager = id;
toggleSidebar = id;
unblockAllSites = id;
unblockSite = id;
viewOnlyThisImage = id;
viewPageSource = id;
viewSource = id;
@ -154,6 +157,7 @@
mLock = NSImageView;
mPageMenu = NSMenu;
mPersonalToolbar = BookmarksToolbar;
mPopupBlocked = NSButton;
mProgress = NSProgressIndicator;
mProxyIcon = PageProxyIcon;
mSearchBar = SearchTextField;

View File

@ -3,7 +3,7 @@
<plist version="1.0">
<dict>
<key>IBDocumentLocation</key>
<string>50 101 653 383 0 0 1024 746 </string>
<string>122 60 653 383 0 0 1280 832 </string>
<key>IBEditorPositions</key>
<dict>
<key>124</key>
@ -23,16 +23,18 @@
<key>463</key>
<string>268 375 213 264 0 0 1280 832 </string>
<key>56</key>
<string>355 485 314 64 0 0 1024 746 </string>
<string>483 539 314 64 0 0 1280 832 </string>
<key>654</key>
<string>159 629 198 144 0 0 1280 832 </string>
<key>731</key>
<string>185 277 654 459 0 0 1024 746 </string>
<key>801</key>
<string>418 469 201 79 0 0 1024 746 </string>
<key>826</key>
<string>96 451 213 78 0 0 1280 832 </string>
</dict>
<key>IBFramework Version</key>
<string>286.0</string>
<string>291.0</string>
<key>IBGroupedObjects</key>
<dict>
<key>7</key>
@ -45,11 +47,7 @@
<string>8</string>
<key>IBLockedObjects</key>
<array/>
<key>IBOpenObjects</key>
<array>
<integer>56</integer>
</array>
<key>IBSystem Version</key>
<string>6L29</string>
<string>6I32</string>
</dict>
</plist>

View File

@ -173,7 +173,7 @@ const int kReuseWindowOnAE = 2;
// initialize if we haven't already.
[self preferenceManager];
[self setupStartpage];
[self setupStartpage];
// register our app components with the embed layer
unsigned int numComps = 0;

View File

@ -107,6 +107,7 @@ typedef enum
IBOutlet NSTextField* mStatus;
IBOutlet NSProgressIndicator* mProgress; // STRONG reference
IBOutlet NSImageView* mLock;
IBOutlet NSButton* mPopupBlocked;
IBOutlet NSWindow* mLocationSheetWindow;
IBOutlet NSTextField* mLocationSheetURLField;
IBOutlet NSView* mStatusBar; // contains the status text, progress bar, and lock
@ -183,6 +184,7 @@ typedef enum
// could be an outlet, but i figure it's easier to get it at runtime thereby saving
// someone from messing up in the nib when making changes.
NSView* mProgressSuperview; // WEAK ptr
NSView* mPopupBlockSuperview; // WEAK ptr
nsIURIFixup* mURIFixer; // [STRONG] should be nsCOMPtr, but can't
nsIBrowserHistory* mGlobalHistory; // [STRONG] should be nsCOMPtr, but can't
@ -205,6 +207,14 @@ typedef enum
// call to update the image of the lock icon with a value from nsIWebProgressListener
- (void)updateLock:(unsigned int)securityState;
// call to update (show/hide) the image of the blocked-popup indicator and handle
// the items of the popup un-blocker menu
- (void)showPopupBlocked:(BOOL)inBlocked;
- (void)buildPopupBlockerMenu:(NSNotification*)notifer;
- (IBAction)unblockSite:(id)sender;
- (IBAction)unblockAllSites:(id)sender;
- (IBAction)configurePopupBlocking:(id)sender;
- (void)performAppropriateLocationAction;
- (IBAction)goToLocationFromToolbarURLField:(id)sender;
- (void)beginLocationSheet;

View File

@ -79,6 +79,7 @@
#include "nsIURI.h"
#include "nsIURIFixup.h"
#include "nsIBrowserHistory.h"
#include "nsIPermissionManager.h"
#include <QuickTime/QuickTime.h>
@ -161,6 +162,52 @@ static NSArray* sToolbarDefaults = nil;
@end
//////////////////////////////////////
#pragma mark -
//
// IconPopUpCell
//
// A popup cell that displays only an icon with no border, yet retains the
// behaviors of a popup menu. It's amazing you can't get this w/out having
// to subclass, but *shrug*.
//
@interface IconPopUpCell : NSPopUpButtonCell
{
@private
NSImage* fImage;
NSRect fSrcRect; // rect cached for drawing, same size as image
}
- (id)initWithImage:(NSImage *)inImage;
@end
@implementation IconPopUpCell
- (id)initWithImage:(NSImage *)inImage
{
if ( (self = [super initTextCell:@"" pullsDown:YES]) )
{
fImage = [inImage retain];
fSrcRect = NSMakeRect(0,0,0,0);
fSrcRect.size = [fImage size];
}
return self;
}
- (void)dealloc
{
[fImage release];
}
- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
{
[fImage setFlipped:[controlView isFlipped]];
cellFrame.size = fSrcRect.size; // don't scale
[fImage drawInRect:cellFrame fromRect:fSrcRect operation:NSCompositeSourceOver fraction:1.0];
}
@end
#pragma mark -
@interface BrowserWindowController(Private)
- (void)setupToolbar;
@ -358,6 +405,7 @@ static NSArray* sToolbarDefaults = nil;
// [mSidebarBrowserView windowClosed];
[mProgress release];
[mPopupBlocked release];
[mSearchBar release];
[self stopThrobber];
[mThrobberImages release];
@ -387,13 +435,18 @@ static NSArray* sToolbarDefaults = nil;
mProgress = nil;
mStatus = nil;
mLock = nil;
mPopupBlocked = nil;
}
else {
// Retain with a single extra refcount. This allows us to remove
// the progress meter from its superview without having to worry
// about retaining and releasing it. Cache the superview of the
// progress. Dynamically fetch the superview so as not to burden
// someone rearranging the nib with this detail.
// someone rearranging the nib with this detail. Note that this
// needs to be in a subview from the status bar because if the
// window resizes while it is hidden, its position wouldn't get updated.
// Having it in a separate view that stays visible (and is thus
// involved in the layout process) solves this.
[mProgress retain];
mProgressSuperview = [mProgress superview];
@ -402,6 +455,26 @@ static NSArray* sToolbarDefaults = nil;
// (radar 2194819), we need to make the text area opaque.
[mStatus setBackgroundColor:[NSColor windowBackgroundColor]];
[mStatus setDrawsBackground:YES];
// create a new cell for our popup blocker item that draws just an image
// yet still retains the functionality of a popdown menu. Like the progress
// meter above, we retain so we can hide with impunity and grab its superview.
// However, unlike the progress meter, this doesn't need to be in a subview from
// the status bar because it is in a fixed position on the LHS.
[mPopupBlocked retain];
NSMenu* savedMenu = [mPopupBlocked menu]; // must cache this before replacing cell
IconPopUpCell* iconCell = [[[IconPopUpCell alloc] initWithImage:[NSImage imageNamed:@"popup-blocked"]] autorelease];
[mPopupBlocked setCell:iconCell];
//[iconCell setPreferredEdge:NSMinYEdge];
[iconCell setMenu:savedMenu];
[iconCell setBordered:NO];
mPopupBlockSuperview = [mPopupBlocked superview];
[self showPopupBlocked:NO];
// register for notifications so we can populate the popup blocker menu
// right before it's displayed.
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(buildPopupBlockerMenu:)
name:NSPopUpButtonCellWillPopUpNotification object:nil];
}
// Set up the toolbar's search text field
@ -2220,6 +2293,128 @@ static NSArray* sToolbarDefaults = nil;
[mProgress removeFromSuperview];
}
//
// - showPopupBlocked:
//
// Show/hide the image of the blocked-popup indicator
//
- (void)showPopupBlocked:(BOOL)inBlocked
{
if ( inBlocked && ![mPopupBlocked window] ) { // told to show, currently hidden
[mPopupBlockSuperview addSubview:mPopupBlocked];
}
else if ( !inBlocked && [mPopupBlocked window] ) { // told to hide, currently visible
[mPopupBlocked removeFromSuperview];
}
}
//
// buildPopupBlockerMenu:
//
// Called by the notification center right before the menu will be displayed. This
// allows us the opportunity to populate its contents from the list of sites
// in the block list.
//
- (void)buildPopupBlockerMenu:(NSNotification*)notifier
{
const long kSeparatorTag = -1;
NSPopUpButton* popup = [notifier object];
// clear out existing menu. loop until we hit our special tag
NSMenu* menu = [popup menu];
int numItemsToDelete = [popup indexOfItemWithTag:kSeparatorTag];
for ( int i = 0; i < numItemsToDelete; ++i )
[popup removeItemAtIndex:0];
// the first item will get swallowed by the popup
[popup insertItemWithTitle:@"" atIndex:0];
// fill in new menu
nsCOMPtr<nsISupportsArray> blockedSites;
[[self getBrowserWrapper] getBlockedSites:getter_AddRefs(blockedSites)];
PRUint32 siteCount = 0;
blockedSites->Count(&siteCount);
for ( PRUint32 i = 0; i < siteCount; ++i ) {
nsCOMPtr<nsISupports> genericURI = dont_AddRef(blockedSites->ElementAt(i));
nsCOMPtr<nsIURI> uri = do_QueryInterface(genericURI);
if ( uri ) {
// extract the host
nsCAutoString host;
uri->GetHost(host);
NSString* hostString = [NSString stringWithCString:host.get()];
// create a new menu item and set its tag to the position in the menu so
// the action can know which site we want to unblock. Insert it at |i+1|
// because we had to pad with one item above, but set the tag to |i| because
// that's the index in the array.
const PRUint32 insertAt = i + 1;
NSString* itemTitle = [NSString stringWithFormat:NSLocalizedString(@"Unblock %@", @"Unblock %@"), hostString];
[popup insertItemWithTitle:itemTitle atIndex:insertAt];
NSMenuItem* currItem = [popup itemAtIndex:insertAt];
[currItem setAction:@selector(unblockSite:)];
[currItem setTarget:self];
[currItem setTag:i];
}
}
}
//
// unblockSite:
//
// Called in response to an item in the unblock popup menu being selected to
// add a particular site to the popup whitelist. We assume that the tag of
// the sender is the index into the blocked sites array stores in the browser
// wrapper to get the nsURI.
//
- (IBAction)unblockSite:(id)sender
{
nsCOMPtr<nsISupportsArray> blockedSites;
[[self getBrowserWrapper] getBlockedSites:getter_AddRefs(blockedSites)];
// get the tag from the sender and use that as the index into the list
long tag = [sender tag];
if ( tag >= 0 ) {
nsCOMPtr<nsISupports> genUri = dont_AddRef(blockedSites->ElementAt(tag));
nsCOMPtr<nsIURI> uri = do_QueryInterface(genUri);
nsCOMPtr<nsIPermissionManager> pm ( do_GetService(NS_PERMISSIONMANAGER_CONTRACTID) );
pm->Add(uri, nsIPermissionManager::POPUP_TYPE, nsIPermissionManager::ALLOW_ACTION);
}
}
//
// - unblockAllSites:
//
// Called in response to the menu item from the unblock popup. Loop over all
// the items in the blocked sites array in the browser wrapper and add them
// to the whitelist.
//
- (IBAction)unblockAllSites:(id)sender
{
nsCOMPtr<nsISupportsArray> blockedSites;
[[self getBrowserWrapper] getBlockedSites:getter_AddRefs(blockedSites)];
nsCOMPtr<nsIPermissionManager> pm ( do_GetService(NS_PERMISSIONMANAGER_CONTRACTID) );
PRUint32 count = 0;
blockedSites->Count(&count);
for ( PRUint32 i = 0; i < count; ++i ) {
nsCOMPtr<nsISupports> genUri = dont_AddRef(blockedSites->ElementAt(i));
nsCOMPtr<nsIURI> uri = do_QueryInterface(genUri);
pm->Add(uri, nsIPermissionManager::POPUP_TYPE, nsIPermissionManager::ALLOW_ACTION);
}
}
//
// -configurePopupBlocking
//
// Show the web features pref panel where the user can do things to configure
// popup blocking
//
- (IBAction)configurePopupBlocking:(id)sender
{
[[NSApp delegate] displayPreferencesWindow:self];
[[[NSApp delegate] preferencesController] selectPreferencePaneByIdentifier:@"org.mozilla.chimera.preference.webfeatures"];
}
//
// updateLock:

View File

@ -42,6 +42,8 @@
@class ToolTip;
@class AutoCompleteTextField;
class nsISupportsArray;
@interface BrowserWrapper : NSView <CHBrowserListener, CHBrowserContainer>
{
AutoCompleteTextField* mUrlbar;
@ -62,6 +64,9 @@
NSString* mTitle;
// the title we use for the tab. This differs for mTitle when the tab is loading
NSString* mTabTitle;
// array of sites that have blocked popups. If nil, no sites are blocked. Cleared
// after each new page.
nsISupportsArray* mBlockedSites; // STRONG
CHBrowserView* mBrowserView;
NSString* mDefaultStatusString;
@ -92,6 +97,8 @@
- (NSString*)getCurrentURLSpec;
- (void)getBlockedSites:(nsISupportsArray**)outSites;
- (void)loadURI:(NSString *)urlSpec referrer:(NSString*)referrer flags:(unsigned int)flags activate:(BOOL)activate;
- (void)makePrimaryBrowserView: (id)aUrlbar status: (id)aStatus
windowController: (BrowserWindowController*)aWindowController;

View File

@ -113,7 +113,8 @@ const NSString* kOfflineNotificationName = @"offlineModeChanged";
mListenersAttached = NO;
mSecureState = nsIWebProgressListener::STATE_IS_INSECURE;
mProgress = 0.0;
mBlockedSites = nsnull;
BOOL gotPref;
BOOL pluginsEnabled = [[PreferenceManager sharedInstance] getBooleanPref:"chimera.enable_plugins" withSuccess:&gotPref];
if (gotPref && !pluginsEnabled)
@ -149,6 +150,8 @@ const NSString* kOfflineNotificationName = @"offlineModeChanged";
[mTitle release];
[mTabTitle release];
NS_IF_RELEASE(mBlockedSites);
[super dealloc];
}
@ -255,6 +258,9 @@ const NSString* kOfflineNotificationName = @"offlineModeChanged";
selector:@selector(offlineModeChanged:)
name:kOfflineNotificationName
object:nil];
// update the blocked popup indicator
[mWindowController showPopupBlocked:(mBlockedSites != nil)];
// Update the URL bar, but only if the user hasn't put something of their
// own in there.
@ -336,6 +342,9 @@ const NSString* kOfflineNotificationName = @"offlineModeChanged";
mLoadingStatusString = [NSLocalizedString(@"TabLoading", @"") retain];
[mStatus setStringValue:mLoadingStatusString];
NS_IF_RELEASE(mBlockedSites);
[mWindowController showPopupBlocked:NO];
mProgress = 0.0;
mIsBusy = YES;
@ -574,6 +583,23 @@ const NSString* kOfflineNotificationName = @"offlineModeChanged";
[mToolTip closeToolTip];
}
//
// - onPopupBlocked:fromSite:
//
// Called when gecko blocks a popup, telling us who it came from. Currently, we
// don't do anything with the blocked URI, but we have it just in case.
//
- (void)onPopupBlocked:(nsIURI*)inURIBlocked fromSite:(nsIURI*)inSite
{
// lazily instantiate.
if ( !mBlockedSites )
NS_NewISupportsArray(&mBlockedSites);
if ( mBlockedSites ) {
mBlockedSites->AppendElement(inSite);
[mWindowController showPopupBlocked:YES];
}
}
// Called when a context menu should be shown.
- (void)onShowContextMenu:(int)flags domEvent:(nsIDOMEvent*)aEvent domNode:(nsIDOMNode*)aNode
{
@ -857,5 +883,12 @@ const NSString* kOfflineNotificationName = @"offlineModeChanged";
return [[self getBrowserView] currentCharset];
}
- (void)getBlockedSites:(nsISupportsArray**)outSites
{
if ( !outSites )
return;
*outSites = mBlockedSites;
NS_IF_ADDREF(*outSites);
}
@end

View File

@ -1023,6 +1023,10 @@ KeychainFormSubmitObserver::CheckChangeDataYN(nsIDOMWindowInternal* window)
{
}
- (void)onPopupBlocked:(nsIURI*)inURIBlocked fromSite:(nsIURI*)inSite
{
}
@end
//

View File

@ -17,6 +17,7 @@
#include "nsIWebProgressListener.h"
#include "nsIEmbeddingSiteWindow2.h"
#include "nsIWindowCreator.h"
#include "nsIDOMEventListener.h"
#include "nsIContextMenuListener.h"
#include "nsITooltipListener.h"
@ -30,6 +31,7 @@ class CHBrowserListener : public nsSupportsWeakReference,
public nsIEmbeddingSiteWindow2,
public nsIWebProgressListener,
public nsIContextMenuListener,
public nsIDOMEventListener,
public nsITooltipListener
{
public:
@ -45,6 +47,7 @@ public:
NS_DECL_NSIWEBPROGRESSLISTENER
NS_DECL_NSICONTEXTMENULISTENER
NS_DECL_NSITOOLTIPLISTENER
NS_DECL_NSIDOMEVENTLISTENER
void AddListener(id <CHBrowserListener> aListener);
void RemoveListener(id <CHBrowserListener> aListener);

View File

@ -50,6 +50,7 @@
#include "nsCRT.h"
#include "nsString.h"
#include "nsCOMPtr.h"
#include "nsIDOMPopupBlockedEvent.h"
#import "CHBrowserView.h"
@ -70,7 +71,7 @@ CHBrowserListener::~CHBrowserListener()
[mContainer release];
}
NS_IMPL_ISUPPORTS9(CHBrowserListener,
NS_IMPL_ISUPPORTS10(CHBrowserListener,
nsIInterfaceRequestor,
nsIWebBrowserChrome,
nsIWindowCreator,
@ -79,6 +80,7 @@ NS_IMPL_ISUPPORTS9(CHBrowserListener,
nsIWebProgressListener,
nsISupportsWeakReference,
nsIContextMenuListener,
nsIDOMEventListener,
nsITooltipListener)
// Implementation of nsIInterfaceRequestor
@ -326,9 +328,6 @@ CHBrowserListener::SetDimensions(PRUint32 flags, PRInt32 x, PRInt32 y, PRInt32 c
{
NSRect frame = [window frame];
float newWidth = (float)cx;
float newHeight = (float)cy;
// should we allow resizes larger than the screen, or smaller
// than some min size here?
@ -626,3 +625,16 @@ CHBrowserListener::SetContainer(id <CHBrowserContainer> aContainer)
[mContainer retain];
}
NS_IMETHODIMP
CHBrowserListener::HandleEvent(nsIDOMEvent *event)
{
nsCOMPtr<nsIDOMPopupBlockedEvent> blockEvent = do_QueryInterface(event);
if ( blockEvent ) {
nsCOMPtr<nsIURI> blockedURI, blockedSite;
blockEvent->GetPopupWindowURI(getter_AddRefs(blockedURI));
blockEvent->GetRequestingWindowURI(getter_AddRefs(blockedSite));
[mContainer onPopupBlocked:blockedURI fromSite:blockedSite];
}
return NS_OK;
}

View File

@ -51,6 +51,7 @@ class nsIWebBrowserFind;
class nsIEventSink;
class nsIDragHelperService;
class nsIPrintSettings;
class nsIURI;
// Protocol implemented by anyone interested in progress
@ -73,7 +74,8 @@ class nsIPrintSettings;
// Called when a tooltip should be shown or hidden
- (void)onShowTooltip:(NSPoint)where withText:(NSString*)text;
- (void)onHideTooltip;
// Called when a popup is blocked
- (void)onPopupBlocked:(nsIURI*)inURIBlocked fromSite:(nsIURI*)inSite;
@end
typedef enum {

View File

@ -177,6 +177,12 @@ const char kDirServiceContractID[] = "@mozilla.org/file/directory_service;1";
nsCOMPtr<nsIDOMEventReceiver> rec(do_QueryInterface(chromeHandler));
if ( rec )
rec->AddEventListenerByIID(clickListener, NS_GET_IID(nsIDOMMouseListener));
// register the CHBrowserListener as an event listener for popup-blocking events
nsCOMPtr<nsIDOMEventTarget> eventTarget = do_QueryInterface(rec);
if ( eventTarget )
rv = eventTarget->AddEventListener(NS_LITERAL_STRING("DOMPopupBlocked"),
NS_STATIC_CAST(nsIDOMEventListener*, _listener), PR_FALSE);
}
return self;
}