author | Matthew Noorenberghe <mozilla@noorenberghe.ca> |
Fri, 25 Sep 2015 13:18:29 -0700 | |
changeset 264690 | 9898e4c1387675ceff6e5c514b2b37dc782ae94a |
parent 264689 | 1c884fcfdf388ceb3bf965d0939e6304e4d0c2c9 |
child 264691 | cc22ed2cafd3f850e00c3b16a45e6a24c1a190bc |
push id | 65707 |
push user | cbook@mozilla.com |
push date | Mon, 28 Sep 2015 12:18:34 +0000 |
treeherder | mozilla-inbound@2c0e60a8f736 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | mstange |
bugs | 1205399 |
milestone | 44.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
new file mode 100644 --- /dev/null +++ b/toolkit/locales/en-US/chrome/alerts/alert.properties @@ -0,0 +1,11 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# LOCALIZATION NOTE(closeButton.title): Used as the close button text for web notifications on OS X. +# This should ideally match the string that OS X uses for the close button on alert-type +# notifications. OS X will truncate the value if it's too long. +closeButton.title = Close +# LOCALIZATION NOTE(actionButton.label): Used as the button label to provide more actions on OS X notifications. OS X will truncate this if it's too long. +actionButton.label = … +webActions.disable.label = Disable notifications from this site
--- a/toolkit/locales/jar.mn +++ b/toolkit/locales/jar.mn @@ -118,16 +118,17 @@ locale/@AB_CD@/mozapps/update/updates.properties (%chrome/mozapps/update/updates.properties) locale/@AB_CD@/mozapps/update/history.dtd (%chrome/mozapps/update/history.dtd) locale/@AB_CD@/mozapps/xpinstall/xpinstallConfirm.dtd (%chrome/mozapps/extensions/xpinstallConfirm.dtd) locale/@AB_CD@/mozapps/xpinstall/xpinstallConfirm.properties (%chrome/mozapps/extensions/xpinstallConfirm.properties) % locale pluginproblem @AB_CD@ %locale/@AB_CD@/pluginproblem/ locale/@AB_CD@/pluginproblem/pluginproblem.dtd (%chrome/pluginproblem/pluginproblem.dtd) % locale alerts @AB_CD@ %locale/@AB_CD@/alerts/ locale/@AB_CD@/alerts/alert.dtd (%chrome/alerts/alert.dtd) + locale/@AB_CD@/alerts/alert.properties (%chrome/alerts/alert.properties) % locale cookie @AB_CD@ %locale/@AB_CD@/cookie/ locale/@AB_CD@/cookie/cookieAcceptDialog.dtd (%chrome/cookie/cookieAcceptDialog.dtd) locale/@AB_CD@/cookie/cookieAcceptDialog.properties (%chrome/cookie/cookieAcceptDialog.properties) % locale formautofill @AB_CD@ %locale/@AB_CD@/formautofill/ locale/@AB_CD@/formautofill/requestAutocomplete.dtd (%chrome/formautofill/requestAutocomplete.dtd) % locale passwordmgr @AB_CD@ %locale/@AB_CD@/passwordmgr/ locale/@AB_CD@/passwordmgr/passwordmgr.properties (%chrome/passwordmgr/passwordmgr.properties) locale/@AB_CD@/passwordmgr/passwordManager.dtd (%chrome/passwordmgr/passwordManager.dtd)
--- a/widget/cocoa/OSXNotificationCenter.h +++ b/widget/cocoa/OSXNotificationCenter.h @@ -1,25 +1,29 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef OSXNotificationCenter_h #define OSXNotificationCenter_h #import <Foundation/Foundation.h> #include "nsIAlertsService.h" #include "imgINotificationObserver.h" #include "nsITimer.h" #include "nsTArray.h" #include "mozilla/RefPtr.h" @class mozNotificationCenterDelegate; +#if !defined(MAC_OS_X_VERSION_10_8) || (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_8) +typedef NSInteger NSUserNotificationActivationType; +#endif + namespace mozilla { class OSXNotificationInfo; class OSXNotificationCenter : public nsIAlertsService, public imgINotificationObserver, public nsITimerCallback { @@ -28,17 +32,18 @@ public: NS_DECL_NSIALERTSSERVICE NS_DECL_IMGINOTIFICATIONOBSERVER NS_DECL_NSITIMERCALLBACK OSXNotificationCenter(); nsresult Init(); void CloseAlertCocoaString(NSString *aAlertName); - void OnClick(NSString *aAlertName); + void OnActivate(NSString *aAlertName, NSUserNotificationActivationType aActivationType, + unsigned long long aAdditionalActionIndex); void ShowPendingNotification(OSXNotificationInfo *osxni); protected: virtual ~OSXNotificationCenter(); private: mozNotificationCenterDelegate *mDelegate; nsTArray<nsRefPtr<OSXNotificationInfo> > mActiveAlerts;
--- a/widget/cocoa/OSXNotificationCenter.mm +++ b/widget/cocoa/OSXNotificationCenter.mm @@ -1,39 +1,52 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "OSXNotificationCenter.h" #import <AppKit/AppKit.h> #include "imgIRequest.h" #include "imgIContainer.h" +#include "nsIStringBundle.h" #include "nsNetUtil.h" #include "imgLoader.h" #import "nsCocoaUtils.h" +#include "nsContentUtils.h" #include "nsObjCExceptions.h" #include "nsString.h" #include "nsCOMPtr.h" #include "nsIObserver.h" #include "nsIContentPolicy.h" #include "imgRequestProxy.h" using namespace mozilla; #if !defined(MAC_OS_X_VERSION_10_8) || (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_8) @protocol NSUserNotificationCenterDelegate @end static NSString * const NSUserNotificationDefaultSoundName = @"DefaultSoundName"; enum { NSUserNotificationActivationTypeNone = 0, NSUserNotificationActivationTypeContentsClicked = 1, - NSUserNotificationActivationTypeActionButtonClicked = 2 + NSUserNotificationActivationTypeActionButtonClicked = 2, }; -typedef NSInteger NSUserNotificationActivationType; +#endif + +#if !defined(MAC_OS_X_VERSION_10_9) || (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_9) +enum { + NSUserNotificationActivationTypeReplied = 3, +}; +#endif + +#if !defined(MAC_OS_X_VERSION_10_10) || (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_10) +enum { + NSUserNotificationActivationTypeAdditionalActionClicked = 4 +}; #endif @protocol FakeNSUserNotification <NSObject> @property (copy) NSString* title; @property (copy) NSString* subtitle; @property (copy) NSString* informativeText; @property (copy) NSString* actionButtonTitle; @property (copy) NSDictionary* userInfo; @@ -85,17 +98,20 @@ typedef NSInteger NSUserNotificationActi didDeliverNotification:(id<FakeNSUserNotification>)notification { } - (void)userNotificationCenter:(id<FakeNSUserNotificationCenter>)center didActivateNotification:(id<FakeNSUserNotification>)notification { - mOSXNC->OnClick([[notification userInfo] valueForKey:@"name"]); + NSNumber *alternateActionIndex = [(NSObject*)notification valueForKey:@"_alternateActionIndex"]; + mOSXNC->OnActivate([[notification userInfo] valueForKey:@"name"], + notification.activationType, + [alternateActionIndex unsignedLongLongValue]); } - (BOOL)userNotificationCenter:(id<FakeNSUserNotificationCenter>)center shouldPresentNotification:(id<FakeNSUserNotification>)notification { return YES; } @@ -105,20 +121,32 @@ typedef NSInteger NSUserNotificationActi didRemoveDeliveredNotifications:(NSArray *)notifications { for (id<FakeNSUserNotification> notification in notifications) { NSString *name = [[notification userInfo] valueForKey:@"name"]; mOSXNC->CloseAlertCocoaString(name); } } +// This is an undocumented method that we need to be notified if a user clicks the close button. +- (void)userNotificationCenter:(id<FakeNSUserNotificationCenter>)center + didDismissAlert:(id<FakeNSUserNotification>)notification +{ + NSString *name = [[notification userInfo] valueForKey:@"name"]; + mOSXNC->CloseAlertCocoaString(name); +} + @end namespace mozilla { +enum { + OSXNotificationActionDisable = 0 +}; + class OSXNotificationInfo { private: ~OSXNotificationInfo(); public: NS_INLINE_DECL_REFCOUNTING(OSXNotificationInfo) OSXNotificationInfo(NSString *name, nsIObserver *observer, const nsAString & alertCookie); @@ -212,16 +240,43 @@ OSXNotificationCenter::ShowAlertNotifica Class unClass = NSClassFromString(@"NSUserNotification"); id<FakeNSUserNotification> notification = [[unClass alloc] init]; notification.title = [NSString stringWithCharacters:(const unichar *)aAlertTitle.BeginReading() length:aAlertTitle.Length()]; notification.informativeText = [NSString stringWithCharacters:(const unichar *)aAlertText.BeginReading() length:aAlertText.Length()]; notification.soundName = NSUserNotificationDefaultSoundName; notification.hasActionButton = NO; + + // If this is not an application/extension alert, show additional actions dealing with permissions. + if (!nsContentUtils::IsSystemOrExpandedPrincipal(aPrincipal) + && !aPrincipal->GetIsNullPrincipal()) { + nsCOMPtr<nsIStringBundleService> sbs = do_GetService(NS_STRINGBUNDLE_CONTRACTID); + nsCOMPtr<nsIStringBundle> bundle; + nsresult rv = sbs->CreateBundle("chrome://alerts/locale/alert.properties", getter_AddRefs(bundle)); + if (NS_SUCCEEDED(rv)) { + nsXPIDLString closeButtonTitle, actionButtonTitle, disableButtonTitle; + bundle->GetStringFromName(NS_LITERAL_STRING("closeButton.title").get(), + getter_Copies(closeButtonTitle)); + bundle->GetStringFromName(NS_LITERAL_STRING("actionButton.label").get(), + getter_Copies(actionButtonTitle)); + bundle->GetStringFromName(NS_LITERAL_STRING("webActions.disable.label").get(), + getter_Copies(disableButtonTitle)); + + notification.hasActionButton = YES; + notification.otherButtonTitle = nsCocoaUtils::ToNSString(closeButtonTitle); + notification.actionButtonTitle = nsCocoaUtils::ToNSString(actionButtonTitle); + [(NSObject*)notification setValue:@(YES) forKey:@"_showsButtons"]; + [(NSObject*)notification setValue:@(YES) forKey:@"_alwaysShowAlternateActionMenu"]; + [(NSObject*)notification setValue:@[ + nsCocoaUtils::ToNSString(disableButtonTitle) + ] + forKey:@"_alternateActionButtonTitles"]; + } + } NSString *alertName = [NSString stringWithCharacters:(const unichar *)aAlertName.BeginReading() length:aAlertName.Length()]; if (!alertName) { return NS_ERROR_FAILURE; } notification.userInfo = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:alertName, nil] forKeys:[NSArray arrayWithObjects:@"name", nil]]; OSXNotificationInfo *osxni = new OSXNotificationInfo(alertName, aAlertListener, aAlertCookie); @@ -313,29 +368,46 @@ OSXNotificationCenter::CloseAlertCocoaSt break; } } NS_OBJC_END_TRY_ABORT_BLOCK; } void -OSXNotificationCenter::OnClick(NSString *aAlertName) +OSXNotificationCenter::OnActivate(NSString *aAlertName, + NSUserNotificationActivationType aActivationType, + unsigned long long aAdditionalActionIndex) { NS_OBJC_BEGIN_TRY_ABORT_BLOCK; if (!aAlertName) { return; // Can't do anything without a name } for (unsigned int i = 0; i < mActiveAlerts.Length(); i++) { OSXNotificationInfo *osxni = mActiveAlerts[i]; if ([aAlertName isEqualToString:osxni->mName]) { if (osxni->mObserver) { - osxni->mObserver->Observe(nullptr, "alertclickcallback", osxni->mCookie.get()); + switch (aActivationType) { + case NSUserNotificationActivationTypeAdditionalActionClicked: + case NSUserNotificationActivationTypeActionButtonClicked: + switch (aAdditionalActionIndex) { + case OSXNotificationActionDisable: + osxni->mObserver->Observe(nullptr, "alertdisablecallback", osxni->mCookie.get()); + break; + default: + NS_WARNING("Unknown NSUserNotification additional action clicked"); + break; + } + break; + default: + osxni->mObserver->Observe(nullptr, "alertclickcallback", osxni->mCookie.get()); + break; + } } return; } } NS_OBJC_END_TRY_ABORT_BLOCK; }