diff --git a/extensions/cookie/nsPermissions.cpp b/extensions/cookie/nsPermissions.cpp index c8dbb28749f..559520a2a83 100644 --- a/extensions/cookie/nsPermissions.cpp +++ b/extensions/cookie/nsPermissions.cpp @@ -353,7 +353,6 @@ Permission_AddHost(const nsAFlatCString & host, PRBool permission, PRInt32 type, typeStruct = NS_STATIC_CAST (permission_TypeStruct*, hostStruct->permissionList->ElementAt(typeIndex)); if (typeStruct->type == type) { - /* type found. Modify the corresponding permission */ typeStruct->permission = permission; typeFound = PR_TRUE; @@ -459,7 +458,6 @@ Permission_Save(PRBool notify) { * host \t permission \t permission ... \n */ - PRInt32 hostCount = permission_list->Count(); for (PRInt32 i = 0; i < hostCount; ++i) { hostStruct = NS_STATIC_CAST(permission_HostStruct*, permission_list->ElementAt(i)); @@ -632,6 +630,29 @@ PERMISSION_HostCount() { return permission_list->Count(); } +PUBLIC PRInt32 +PERMISSION_HostCountForType(PRInt32 type) { + if (!permission_list) { + return 0; + } + + permission_HostStruct * hostStruct; + permission_TypeStruct * typeStruct; + PRInt32 hostCount = permission_list->Count(); + PRInt32 hostCountForType = 0; + for (PRInt32 i = 0; i < hostCount; ++i) { + hostStruct = NS_STATIC_CAST(permission_HostStruct*, permission_list->ElementAt(i)); + PRInt32 typeCount = hostStruct->permissionList->Count(); + for (PRInt32 j = 0; j < typeCount; ++j) { + typeStruct = NS_STATIC_CAST(permission_TypeStruct *, hostStruct->permissionList->ElementAt(j)); + if (typeStruct && typeStruct->type == type) + hostCountForType++; + } + } + + return hostCountForType; +} + PUBLIC PRInt32 PERMISSION_TypeCount(PRInt32 host) { if (!permission_list) { diff --git a/extensions/cookie/nsPermissions.h b/extensions/cookie/nsPermissions.h index 55ede6b768d..1caac2bd2ab 100644 --- a/extensions/cookie/nsPermissions.h +++ b/extensions/cookie/nsPermissions.h @@ -66,6 +66,7 @@ extern void PERMISSION_RemoveAll(); extern void PERMISSION_DeletePersistentUserData(void); extern PRInt32 PERMISSION_HostCount(); +extern PRInt32 PERMISSION_HostCountForType(PRInt32 type); extern PRInt32 PERMISSION_TypeCount(PRInt32 host); extern nsresult PERMISSION_Enumerate (PRInt32 hostNumber, PRInt32 typeNumber, char **host, PRInt32 *type, PRBool *capability); diff --git a/extensions/cookie/nsPopupWindowManager.cpp b/extensions/cookie/nsPopupWindowManager.cpp index 1f4565b4504..d3398b43dc4 100644 --- a/extensions/cookie/nsPopupWindowManager.cpp +++ b/extensions/cookie/nsPopupWindowManager.cpp @@ -40,6 +40,7 @@ #include "nsCOMPtr.h" #include "nsCRT.h" #include "nsPermissions.h" +#include "nsPermission.h" #include "nsIObserverService.h" #include "nsIPrefBranch.h" @@ -58,6 +59,58 @@ static const char sPermissionChangeNotification[] = PPM_CHANGE_NOTIFICATION; static const char sXPCOMShutdownTopic[] = NS_XPCOM_SHUTDOWN_OBSERVER_ID; static const char sPrefChangedTopic[] = NS_PREFBRANCH_PREFCHANGE_TOPIC_ID; +class nsPopupEnumerator : public nsISimpleEnumerator +{ + public: + + NS_DECL_ISUPPORTS + + nsPopupEnumerator() : mHostCurrent(0), mTypeCurrent(0) + { + mHostCount = PERMISSION_HostCountForType(WINDOWPERMISSION); + } + + NS_IMETHOD HasMoreElements(PRBool *result) + { + *result = mHostCount > mHostCurrent; + return NS_OK; + } + + NS_IMETHOD GetNext(nsISupports **result) + { + char *host; + PRBool capability; + PRInt32 type; + + *result = nsnull; + + while (NS_SUCCEEDED(PERMISSION_Enumerate(mHostCurrent, mTypeCurrent++, &host, &type, &capability))) { + if ((mTypeCurrent == PERMISSION_TypeCount(mHostCurrent)) || (type == WINDOWPERMISSION)) { + mTypeCurrent = 0; + mHostCurrent++; + } + if (type == WINDOWPERMISSION) { + nsIPermission *permission = new nsPermission(host, type, capability); + *result = permission; + NS_ADDREF(*result); + break; + } + } + return NS_OK; + } + + virtual ~nsPopupEnumerator() + { + } + + protected: + PRInt32 mHostCurrent; + PRInt32 mTypeCurrent; + PRInt32 mHostCount; +}; + +NS_IMPL_ISUPPORTS1(nsPopupEnumerator, nsISimpleEnumerator); + //***************************************************************************** //*** nsPopupWindowManager object management and nsISupports //***************************************************************************** @@ -123,14 +176,15 @@ nsPopupWindowManager::Add(nsIURI *aURI, PRBool aPermit) // if we couldn't initialize the permission manager Permission_AddHost() // will create a new list that could stomp an existing cookperm.txt return NS_ERROR_FAILURE; - + nsCAutoString uri; aURI->GetHostPort(uri); if (uri.IsEmpty()) return NS_ERROR_FAILURE; - + if (NS_SUCCEEDED(Permission_AddHost(uri, aPermit, WINDOWPERMISSION, PR_TRUE))) return NotifyObservers(aURI); + return NS_ERROR_FAILURE; } @@ -205,10 +259,15 @@ nsPopupWindowManager::TestPermission(nsIURI *aURI, PRUint32 *_retval) NS_IMETHODIMP nsPopupWindowManager::GetEnumerator(nsISimpleEnumerator **_retval) { - NS_ENSURE_ARG_POINTER(_retval); - *_retval = 0; + *_retval = nsnull; - return NS_ERROR_NOT_IMPLEMENTED; + nsPopupEnumerator* popupEnum = new nsPopupEnumerator(); + if (popupEnum == nsnull) + return NS_ERROR_OUT_OF_MEMORY; + + NS_ADDREF(popupEnum); + *_retval = popupEnum; + return NS_OK; } NS_IMETHODIMP diff --git a/extensions/cookie/resources/content/cookieNavigatorOverlay.xul b/extensions/cookie/resources/content/cookieNavigatorOverlay.xul index 489fcac7e86..a5dda685466 100644 --- a/extensions/cookie/resources/content/cookieNavigatorOverlay.xul +++ b/extensions/cookie/resources/content/cookieNavigatorOverlay.xul @@ -70,7 +70,7 @@ // determine current state (blocked or unblocked) and hide appropriate menu item var blocked; - + blocked = permissionmanager.testForBlocking(window._content.location, COOKIEPERMISSION); enableElement("AllowCookies", blocked); @@ -80,7 +80,7 @@ permissionmanager.testForBlocking(window._content.location, IMAGEPERMISSION); enableElement("AllowImages", blocked); enableElement("BlockImages", !blocked); - + SetPopupMenuEnabledState(); var pref; @@ -104,19 +104,31 @@ } function SetPopupMenuEnabledState() { - // use care choosing which nsIPopupWindowManager constant to compare - // against. the allow/disallow/sometimes relationship can be subtle. - var useManager = !pref.getBoolPref("dom.disable_open_during_load"); var suitable = false; - var enableBlock = false; - if (useManager) { - suitable = popupmanager.testSuitability(getBrowser().currentURI); - if (suitable) - enableBlock = popupmanager.testPermission(getBrowser().currentURI) != Components.interfaces.nsIPopupWindowManager.DENY_POPUP; + var blocked = false; + var policy = pref.getBoolPref("dom.disable_open_during_load"); + + suitable = popupmanager.testSuitability(getBrowser().currentURI); + if (suitable) { + if (!policy) // blacklist, test if there is a permission set + blocked = (popupmanager.testPermission(getBrowser().currentURI) == Components.interfaces.nsIPopupWindowManager.DENY_POPUP); + else { // whitelist, check if it is on list + blocked = true; + var enumerator = popupmanager.getEnumerator(); + while (enumerator.hasMoreElements()) { + var permission = enumerator.getNext() + .QueryInterface(Components.interfaces.nsIPermission); + if (permission.capability && getBrowser().currentURI.host == permission.host) { + blocked = false; + break; + } + } + } } - enableElement("BlockPopups", useManager && suitable && enableBlock); - enableElement("AllowPopups", useManager && suitable && !enableBlock); - enableElement("ManagePopups", useManager); + + enableElement("BlockPopups", suitable && !blocked); + enableElement("AllowPopups", suitable && blocked); + enableElement("ManagePopups", true); } function enableElement(elementID, enable) { @@ -156,19 +168,45 @@ element = document.getElementById("BlockImages"); alert(element.getAttribute("msg")); break; - case "popupAllow": - popupmanager.add(getBrowser().currentURI, true); - element = document.getElementById("AllowPopups"); - alert(element.getAttribute("msg")); - break; - case "popupBlock": - popupmanager.add(getBrowser().currentURI, false); - element = document.getElementById("BlockPopups"); - alert(element.getAttribute("msg")); - break; default: } - } + } + + function PopupAction(action) { + var policy = pref.getBoolPref("dom.disable_open_during_load"); + var uri = getBrowser().currentURI; + + switch (action) { + case "block": + if (!policy) + popupmanager.add(uri, policy); + else + popupmanager.remove(uri); + break; + case "allow": + var browsers = getBrowser().browsers; + var popupIcon = document.getElementById("popupIcon"); + if (!policy) + popupmanager.remove(uri); + else + popupmanager.add(uri, policy); + for (var i = 0; i < browsers.length; i++) { + if (browsers[i].popupDomain == uri.host) { + browsers[i].popupDomain = null; + popupIcon.hidden = true; + } + } + break; + } + } + + function ViewPopupManager() { + window.openDialog("chrome://communicator/content/popupManager.xul", "", + "chrome,resizable=yes,modal=yes", + pref.getBoolPref("dom.disable_open_during_load"), + "", + false); + } ]]> @@ -220,15 +258,15 @@ + oncommand="PopupAction('block');"/> + oncommand="PopupAction('allow');"/> + oncommand="ViewPopupManager();"/> diff --git a/extensions/cookie/resources/content/cookiePrefsOverlay.xul b/extensions/cookie/resources/content/cookiePrefsOverlay.xul index 0d4ec86138a..f7227a9413d 100644 --- a/extensions/cookie/resources/content/cookiePrefsOverlay.xul +++ b/extensions/cookie/resources/content/cookiePrefsOverlay.xul @@ -40,14 +40,12 @@ label="&images.label;"/> - diff --git a/extensions/cookie/resources/content/pref-popups.xul b/extensions/cookie/resources/content/pref-popups.xul index 117b4bbeaed..0062f121886 100644 --- a/extensions/cookie/resources/content/pref-popups.xul +++ b/extensions/cookie/resources/content/pref-popups.xul @@ -48,69 +48,143 @@ onload="init()" headertitle="&title;"> - + var _elementIDs = ["popupPolicy","playSound","playSoundUrl","displayIcon"]; - - + var gPolicyButton; + var gSoundCheckbox; + var gSoundUrlBox; + var gSoundUrlButton; + var gIconCheckbox; - &popupDetails; + const POPUP_TYPE = 2; - - - - - + function init() { + parent.initPanel("chrome://cookie/content/pref-popups.xul"); -