File:  [mozdev] / chimera / MyBrowserView.mm
Revision 1.32: download - view: text, annotated - select for diffs - revision graph
Wed Apr 17 19:33:46 2002 UTC (17 years, 1 month ago) by hyatt
Branches: MAIN
CVS tags: HEAD
Simplifying the popup blocker.

    1: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
    2: /* ***** BEGIN LICENSE BLOCK *****
    3:  * Version: NPL 1.1/GPL 2.0/LGPL 2.1
    4:  *
    5:  * The contents of this file are subject to the Netscape Public License
    6:  * Version 1.1 (the "License"); you may not use this file except in
    7:  * compliance with the License. You may obtain a copy of the License at
    8:  * http://www.mozilla.org/NPL/
    9:  *
   10:  * Software distributed under the License is distributed on an "AS IS" basis,
   11:  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
   12:  * for the specific language governing rights and limitations under the
   13:  * License.
   14:  *
   15:  * The Original Code is mozilla.org code.
   16:  *
   17:  * The Initial Developer of the Original Code is 
   18:  * Netscape Communications Corporation.
   19:  * Portions created by the Initial Developer are Copyright (C) 2002
   20:  * the Initial Developer. All Rights Reserved.
   21:  *
   22:  * Contributor(s):
   23:  *
   24:  * Alternatively, the contents of this file may be used under the terms of
   25:  * either the GNU General Public License Version 2 or later (the "GPL"), or 
   26:  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
   27:  * in which case the provisions of the GPL or the LGPL are applicable instead
   28:  * of those above. If you wish to allow use of your version of this file only
   29:  * under the terms of either the GPL or the LGPL, and not to allow others to
   30:  * use your version of this file under the terms of the NPL, indicate your
   31:  * decision by deleting the provisions above and replace them with the notice
   32:  * and other provisions required by the GPL or the LGPL. If you do not delete
   33:  * the provisions above, a recipient may use your version of this file under
   34:  * the terms of any one of the NPL, the GPL or the LGPL.
   35:  *
   36:  * ***** END LICENSE BLOCK ***** */
   37: 
   38: #import "MyBrowserView.h"
   39: #import "BrowserWindowController.h"
   40: 
   41: #include "nsCOMPtr.h"
   42: #include "nsIServiceManager.h"
   43: #include "nsIIOService.h"
   44: #include "ContentClickListener.h"
   45: #include "nsIDOMWindow.h"
   46: #include "nsIChromeEventHandler.h"
   47: #include "nsPIDOMWindow.h"
   48: #include "nsIDOMEventReceiver.h"
   49: #include "nsIPrefBranch.h"
   50: #include "nsIPrefService.h"
   51: #include "nsCocoaBrowserService.h"
   52: 
   53: #define DOCUMENT_DONE_STRING @"Document: Done"
   54: #define LOADING_STRING @"Loading..."
   55: 
   56: static const char* ioServiceContractID = "@mozilla.org/network/io-service;1";
   57: 
   58: @implementation MyBrowserView
   59: 
   60: -(void)windowClosed
   61: {
   62:   // Break the cycle.
   63:   [browserView destroyWebBrowser];
   64:   [browserView setContainer: nil];
   65:   [browserView removeListener: self];
   66: }
   67: 
   68: -(void)dealloc
   69: {
   70:   printf("My browser view died.\n");
   71: 
   72:   [[NSNotificationCenter defaultCenter] removeObserver: self];
   73:     
   74: 	[defaultStatus release];
   75:   [loadingStatus release];
   76: 
   77:   [super dealloc];
   78: }
   79: 
   80: - (IBAction)load:(id)sender
   81: {
   82:   [browserView loadURI:[NSURL URLWithString:[urlbar stringValue]] flags:NSLoadFlagsNone];
   83: }
   84: 
   85: -(void)disconnectView
   86: {
   87:     urlbar = nil;
   88:     status = nil;
   89:     progress = nil;
   90:     progressSuper = nil;
   91:     mIsPrimary = NO;
   92:     [[NSNotificationCenter defaultCenter] removeObserver:self];
   93:     
   94:     [browserView setActive: NO];
   95: }
   96: 
   97: - (id)initWithFrame:(NSRect)frameRect
   98: {
   99:     [super initWithFrame: frameRect];
  100:      browserView = [[[NSBrowserView alloc] initWithFrame:[self bounds]] autorelease];
  101:     [self addSubview:browserView];
  102:     [browserView setContainer:self];
  103:     [browserView addListener:self];
  104:     mIsBusy = NO;
  105:     mListenersAttached = NO;
  106:     return self;
  107: }
  108: 
  109: -(void)setTab: (NSTabViewItem*)tab
  110: {
  111:   mTab = tab;
  112: }
  113: 
  114: -(void)makePrimaryBrowserView: (id)aUrlbar status: (id)aStatus
  115:     progress: (id)aProgress windowController: aWindowController
  116: {
  117:   urlbar = aUrlbar;
  118:   status = aStatus;
  119:   progress = aProgress;
  120:   progressSuper = [aProgress superview];
  121:   mWindowController = aWindowController;
  122:   
  123:   if (!mIsBusy)
  124:       [progress removeFromSuperview];
  125:   
  126:   defaultStatus = NULL;
  127:   loadingStatus = DOCUMENT_DONE_STRING;
  128:   [status setStringValue:loadingStatus];
  129:   
  130:   mIsPrimary = YES;
  131: 
  132:   if ([[self window] isKeyWindow])
  133:     [browserView setActive: YES];
  134:   
  135:   nsCOMPtr<nsIIOService> ioService(do_GetService(ioServiceContractID));
  136:   if (!ioService)
  137:     return;
  138:   PRBool offline = PR_FALSE;
  139:   ioService->GetOffline(&offline);
  140:   mOffline = offline;
  141:   
  142:   if (mWindowController) // Only register if we're the content area.
  143:     [[NSNotificationCenter defaultCenter] addObserver:self
  144:         selector:@selector(offlineModeChanged:)
  145:         name:@"offlineModeChanged"
  146:         object:nil];
  147:         
  148:   // Update the URL bar.
  149:   [mWindowController updateLocationFields:[self getCurrentURLSpec]];
  150:   
  151:   if (mWindowController && !mListenersAttached) {
  152:     mListenersAttached = YES;
  153:     
  154:     // We need to hook up our click and context menu listeners.
  155:     ContentClickListener* clickListener = new ContentClickListener(mWindowController);
  156:     if (!clickListener)
  157:       return;
  158:     
  159:     nsCOMPtr<nsIDOMWindow> contentWindow = getter_AddRefs([[self getBrowserView] getContentWindow]);
  160:     nsCOMPtr<nsPIDOMWindow> piWindow(do_QueryInterface(contentWindow));
  161:     nsCOMPtr<nsIChromeEventHandler> chromeHandler;
  162:     piWindow->GetChromeEventHandler(getter_AddRefs(chromeHandler));
  163:     nsCOMPtr<nsIDOMEventReceiver> rec(do_QueryInterface(chromeHandler));
  164:     rec->AddEventListenerByIID(clickListener, NS_GET_IID(nsIDOMMouseListener));
  165:   }
  166: }
  167: 
  168: -(NSString*)getCurrentURLSpec
  169: {
  170:   return [browserView getCurrentURLSpec];
  171: }
  172: 
  173: - (void)awakeFromNib 
  174: {
  175: }
  176: 
  177: - (void)setFrame:(NSRect)frameRect
  178: {
  179:   [super setFrame:frameRect];
  180:   NSRect bounds = [self bounds];
  181:   [browserView setFrame:bounds];
  182: }
  183: 
  184: -(BOOL)isBusy
  185: {
  186:   return mIsBusy;
  187: }
  188: 
  189: - (void)onLoadingStarted 
  190: {
  191:   if (defaultStatus) {
  192:     [defaultStatus release];
  193:     defaultStatus = NULL;
  194:   }
  195: 
  196:   [progressSuper addSubview:progress];
  197:   [progress setIndeterminate:YES];
  198:   [progress startAnimation:self];
  199: 
  200:   loadingStatus = LOADING_STRING;
  201:   [status setStringValue:loadingStatus];
  202: 
  203:   mIsBusy = YES;
  204:   [mTab setLabel: LOADING_STRING];
  205:   
  206:   if (mWindowController)
  207:     [mWindowController updateToolbarItems];
  208: }
  209: 
  210: - (void)onLoadingCompleted:(BOOL)succeeded
  211: {
  212:   [progress setIndeterminate:YES];
  213:   [progress stopAnimation:self];
  214:   [progress removeFromSuperview];
  215: 
  216:   loadingStatus = DOCUMENT_DONE_STRING;
  217:   if (defaultStatus) {
  218:     [status setStringValue:defaultStatus];
  219:   }
  220:   else {
  221:     [status setStringValue:loadingStatus];
  222:   }
  223: 
  224:   mIsBusy = NO;
  225:   
  226:   if (mWindowController)
  227:     [mWindowController updateToolbarItems];
  228: }
  229: 
  230: - (void)onProgressChange:(int)currentBytes outOf:(int)maxBytes 
  231: {
  232:   if (maxBytes > 0) {
  233:     BOOL isIndeterminate = [progress isIndeterminate];
  234:     if (isIndeterminate) {
  235:       [progress setIndeterminate:NO];
  236:     }
  237:     double val = ((double)currentBytes / (double)maxBytes) * 100.0;
  238:     [progress setDoubleValue:val];
  239:   }
  240: }
  241: 
  242: - (void)onLocationChange:(NSURL*)url 
  243: {
  244:   NSString* spec = [url absoluteString];
  245:   [mWindowController updateLocationFields:spec];
  246: }
  247: 
  248: - (void)onStatusChange:(NSString*)aStatusString
  249: {
  250:   [status setStringValue: aStatusString];
  251: }
  252: 
  253: - (void)setStatus:(NSString *)statusString ofType:(NSStatusType)type 
  254: {
  255:   if (type == NSStatusTypeScriptDefault) {
  256:     if (defaultStatus) {
  257:       [defaultStatus release];
  258:     }
  259:     defaultStatus = statusString;
  260:     if (defaultStatus) {
  261:       [defaultStatus retain];
  262:     }
  263:   }
  264:   else if (!statusString) {
  265:     if (defaultStatus) {
  266:       [status setStringValue:defaultStatus];
  267:     }
  268:     else {
  269:       [status setStringValue:loadingStatus];
  270:     }      
  271:   }
  272:   else {
  273:     [status setStringValue:statusString];
  274:   }
  275: }
  276: 
  277: - (NSString *)title 
  278: {
  279:   return [[mWindowController window] title];
  280: }
  281: 
  282: - (void)setTitle:(NSString *)title
  283: {
  284:     // We must be the primary content area.
  285:     if (mIsPrimary && mWindowController) {
  286:         if (mOffline) {
  287:             NSString* newTitle;
  288:             if (title && ![title isEqualToString:@""])
  289:                 newTitle = [title stringByAppendingString: @" [Working Offline]"];
  290:             else
  291:                 newTitle = @"Untitled [Working Offline]";
  292:             [[mWindowController window] setTitle: newTitle];
  293:         }
  294:         else {
  295:             if (title && ![title isEqualToString:@""])
  296:                 [[mWindowController window] setTitle:title];
  297:             else
  298:                 [[mWindowController window] setTitle:@"Untitled"];
  299:         }
  300:     }
  301:     
  302:     // Always set the tab.
  303:     if (title && ![title isEqualToString:@""])
  304:         [mTab setLabel:title];
  305:     else
  306:         [mTab setLabel:@"Untitled"];
  307: }
  308: 
  309: // Called when a context menu should be shown.
  310: - (void)onShowContextMenu:(int)flags domEvent:(nsIDOMEvent*)aEvent domNode:(nsIDOMNode*)aNode
  311: {
  312:   [mWindowController onShowContextMenu: flags domEvent: aEvent domNode: aNode];
  313: }
  314: 
  315: -(NSMenu*)getContextMenu
  316: {
  317:   return [mWindowController getContextMenu];
  318: }
  319: 
  320: - (void)offlineModeChanged: (NSNotification*)aNotification
  321: {
  322:     nsCOMPtr<nsIIOService> ioService(do_GetService(ioServiceContractID));
  323:     if (!ioService)
  324:         return;
  325:     PRBool offline = PR_FALSE;
  326:     ioService->GetOffline(&offline);
  327:     mOffline = offline;
  328:     
  329:     if (mOffline) {
  330:         NSString* newTitle = [[[mWindowController window] title] stringByAppendingString: @" [Working Offline]"];
  331:         [[mWindowController window] setTitle: newTitle];
  332:     }
  333:     else {
  334:         NSArray* titleItems = [[[mWindowController window] title] componentsSeparatedByString:@" [Working Offline]"];
  335:         [[mWindowController window] setTitle: [titleItems objectAtIndex: 0]];
  336:     }
  337: }
  338: 
  339: - (void)sizeBrowserTo:(NSSize)dimensions
  340: {
  341:   NSRect bounds = [self bounds];
  342:   float dx = dimensions.width - bounds.size.width;
  343:   float dy = dimensions.height - bounds.size.height;
  344: 
  345:   NSRect frame = [[self window] frame];
  346:   frame.size.width += dx;
  347:   frame.size.height += dy;
  348: 
  349:   [[self window] setFrame:frame display:YES];
  350: }
  351: 
  352: #define NS_POPUP_BLOCK @"This Web site is attempting to open an unrequested popup window.  Navigator can \
  353: automatically prevent Web sites from opening popup advertisements.  Click OK to prevent all \
  354: unrequested popups (including this one) from opening."
  355: 
  356: - (NSBrowserView*)createBrowserWindow:(unsigned int)aMask
  357: {
  358:   nsCOMPtr<nsIPrefBranch> pref(do_GetService("@mozilla.org/preferences-service;1"));
  359:   if (!pref)
  360:     return NS_OK; // Something bad happened if we can't get prefs.
  361: 
  362:   PRBool showBlocker;
  363:   pref->GetBoolPref("browser.popups.showPopupBlocker", &showBlocker);
  364: 
  365:   if (showBlocker) {
  366:     nsCOMPtr<nsIDOMWindow> domWindow = getter_AddRefs([browserView getContentWindow]);
  367:     nsCOMPtr<nsPIDOMWindow> piWindow(do_QueryInterface(domWindow));
  368:     PRBool isUnrequested;
  369:     piWindow->IsLoadingOrRunningTimeout(&isUnrequested);
  370:     if (isUnrequested) {
  371:       // A popup is being opened while the page is currently loading.  Offer to block the
  372:       // popup.
  373:       nsAlertController* controller = nsCocoaBrowserService::GetAlertController();
  374:       BOOL confirm = [controller confirm: [self window] title: @"Unrequested Popup Detected"
  375:                                 text: NS_POPUP_BLOCK];
  376: 
  377:       // This is a one-time dialog.
  378:       pref->SetBoolPref("browser.popups.showPopupBlocker", PR_FALSE);
  379:       
  380:       if (confirm) {
  381:         pref->SetBoolPref("dom.disable_open_during_load", PR_TRUE);
  382:         pref->SetIntPref("dom.disable_open_click_delay", 1000);
  383:       }
  384: 
  385:       nsCOMPtr<nsIPrefService> prefService(do_QueryInterface(pref));
  386:       prefService->SavePrefFile(nsnull);
  387:       
  388:       if (confirm)
  389:         return nil;
  390:     }
  391:   }
  392:   
  393:   BrowserWindowController* controller = [[BrowserWindowController alloc] initWithWindowNibName: @"BrowserWindow"];
  394:   [controller setChromeMask: aMask];
  395:   [controller disableAutosave]; // The Web page opened this window, so we don't ever use its settings.
  396:   [controller enterModalSession];
  397:   [[[controller getMyBrowserView] getBrowserView] setActive: YES];
  398:   return [[controller getMyBrowserView] getBrowserView];
  399: }
  400: 
  401: - (NSBrowserView*)getBrowserView
  402: {
  403:   return browserView;
  404: }
  405: 
  406: @end

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>