--- a/browser/base/content/browser-pageActions.js
+++ b/browser/base/content/browser-pageActions.js
@@ -1253,8 +1253,65 @@ BrowserPageActions.addSearchEngine = {
let prompt = Services.prompt.getPrompt(gBrowser.contentWindow, Ci.nsIPrompt);
prompt.QueryInterface(Ci.nsIWritablePropertyBag2);
prompt.setPropertyAsBool("allowTabModal", true);
prompt.alert(title, text);
},
});
},
};
+
+// share URL
+BrowserPageActions.shareURL = {
+ onShowingInPanel(buttonNode) {
+ this._cached = false;
+ },
+
+ onPlacedInPanel(buttonNode) {
+ let action = PageActions.actionForID("shareURL");
+ BrowserPageActions.takeActionTitleFromPanel(action);
+ },
+
+ onShowingSubview(panelViewNode) {
+ // We cache the providers + the UI if the user selects the share
+ // panel multiple times while the panel is open.
+ if (this._cached) {
+ return;
+ }
+
+ let sharingService = this._sharingService;
+ let url = gBrowser.selectedBrowser.currentURI;
+ let currentURI = gURLBar.makeURIReadable(url).displaySpec;
+ let shareProviders = sharingService.getSharingProviders(currentURI);
+ let fragment = document.createDocumentFragment();
+
+ shareProviders.forEach(function(share) {
+ let item = document.createElement("toolbarbutton");
+ item.setAttribute("label", share.menuItemTitle);
+ item.setAttribute("share-title", share.title);
+ item.setAttribute("image", share.image);
+ item.classList.add("subviewbutton", "subviewbutton-iconic");
+
+ item.addEventListener("command", event => {
+ let shareTitle = event.target.getAttribute("share-title");
+ if (shareTitle) {
+ sharingService.shareUrl(shareTitle, currentURI);
+ }
+ PanelMultiView.hidePopup(BrowserPageActions.panelNode);
+ });
+
+ fragment.appendChild(item);
+ });
+
+ let bodyNode = panelViewNode.querySelector(".panel-subview-body");
+ while (bodyNode.firstChild) {
+ bodyNode.firstChild.remove();
+ }
+ bodyNode.appendChild(fragment);
+ this._cached = true;
+ }
+};
+
+// Attach sharingService here so tests can override the implementation
+XPCOMUtils.defineLazyServiceGetter(BrowserPageActions.shareURL,
+ "_sharingService",
+ "@mozilla.org/widget/macsharingservice;1",
+ "nsIMacSharingService");
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -435,17 +435,18 @@
flip="slide"
photon="true"
position="bottomcenter topright"
tabspecific="true"
noautofocus="true"
copyURL-title="&pageAction.copyLink.label;"
emailLink-title="&emailPageCmd.label;"
sendToDevice-title="&pageAction.sendTabToDevice.label;"
- sendToDevice-notReadyTitle="&sendToDevice.syncNotReady.label;">
+ sendToDevice-notReadyTitle="&sendToDevice.syncNotReady.label;"
+ shareURL-title="&pageAction.shareUrl.label;">
<panelmultiview id="pageActionPanelMultiView"
mainViewId="pageActionPanelMainView"
viewCacheId="appMenu-viewCache">
<panelview id="pageActionPanelMainView"
context="pageActionContextMenu"
class="PanelUI-subView">
<vbox class="panel-subview-body"/>
</panelview>
--- a/browser/base/content/test/urlbar/browser.ini
+++ b/browser/base/content/test/urlbar/browser.ini
@@ -47,16 +47,18 @@ support-files =
page_action_menu_add_search_engine_one.html
page_action_menu_add_search_engine_many.html
page_action_menu_add_search_engine_same_names.html
page_action_menu_add_search_engine_0.xml
page_action_menu_add_search_engine_1.xml
page_action_menu_add_search_engine_2.xml
[browser_page_action_menu_clipboard.js]
subsuite = clipboard
+[browser_page_action_menu_share_mac.js]
+skip-if = os != "mac" # Mac only feature
[browser_pasteAndGo.js]
subsuite = clipboard
[browser_removeUnsafeProtocolsFromURLBarPaste.js]
subsuite = clipboard
[browser_search_favicon.js]
[browser_tabMatchesInAwesomebar.js]
support-files =
moz.png
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/urlbar/browser_page_action_menu_share_mac.js
@@ -0,0 +1,72 @@
+/* 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/. */
+
+"use strict";
+
+/* global sinon */
+Services.scriptloader.loadSubScript("resource://testing-common/sinon-2.3.2.js");
+
+// Keep track of title of service we chose to share with
+let sharedTitle;
+let sharedUrl;
+
+let mockShareData = [{
+ title: "NSA",
+ menuItemTitle: "National Security Agency",
+ image: "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEA" +
+ "LAAAAAABAAEAAAICTAEAOw=="
+}];
+
+let stub = sinon.stub(BrowserPageActions.shareURL, "_sharingService").get(() => {
+ return {
+ getSharingProviders(url) {
+ return mockShareData;
+ },
+ shareUrl(title, url) {
+ sharedUrl = url;
+ sharedTitle = title;
+ }
+ };
+});
+
+registerCleanupFunction(async function() {
+ stub.restore();
+ delete window.sinon;
+ await EventUtils.synthesizeNativeMouseMove(document.documentElement, 0, 0);
+ await PlacesUtils.history.clear();
+});
+
+add_task(async function shareURL() {
+ // Open an actionable page so that the main page action button appears. (It
+ // does not appear on about:blank for example.)
+ let url = "http://example.org/";
+
+ await BrowserTestUtils.withNewTab(url, async () => {
+ // Open the panel.
+ await promisePageActionPanelOpen();
+
+ // Click Share URL.
+ let shareURLButton = document.getElementById("pageAction-panel-shareURL");
+ let viewPromise = promisePageActionViewShown();
+ EventUtils.synthesizeMouseAtCenter(shareURLButton, {});
+
+ let view = await viewPromise;
+ let body = document.getElementById(view.id + "-body");
+
+ Assert.equal(body.childNodes.length, 1, "Has correct share receivers");
+ let shareButton = body.childNodes[0];
+ Assert.equal(shareButton.label, mockShareData[0].menuItemTitle);
+ let hiddenPromise = promisePageActionPanelHidden();
+ // Click on share, panel should hide and sharingService should be
+ // given the title of service to share with
+ EventUtils.synthesizeMouseAtCenter(shareButton, {});
+ await hiddenPromise;
+
+ Assert.equal(sharedTitle, mockShareData[0].title,
+ "Shared with the correct title");
+ Assert.equal(sharedUrl, "http://example.org/",
+ "Shared correct URL");
+
+ });
+});
--- a/browser/base/content/test/urlbar/browser_search_favicon.js
+++ b/browser/base/content/test/urlbar/browser_search_favicon.js
@@ -6,16 +6,20 @@ registerCleanupFunction(() => {
Services.prefs.clearUserPref(gRestyleSearchesPref);
Services.search.currentEngine = gOriginalEngine;
Services.search.removeEngine(gEngine);
return PlacesUtils.history.clear();
});
add_task(async function() {
Services.prefs.setBoolPref(gRestyleSearchesPref, true);
+
+ // This test is sensitive to the mouse position hovering awesome
+ // bar elements, so make sure it doesnt
+ await EventUtils.synthesizeNativeMouseMove(document.documentElement, 0, 0);
});
add_task(async function() {
Services.search.addEngineWithDetails("SearchEngine", "", "", "",
"GET", "http://s.example.com/search");
gEngine = Services.search.getEngineByName("SearchEngine");
gEngine.addParam("q", "{searchTerms}", null);
--- a/browser/locales/en-US/chrome/browser/browser.dtd
+++ b/browser/locales/en-US/chrome/browser/browser.dtd
@@ -989,16 +989,18 @@ you can use these alternative items. Oth
<!ENTITY pageAction.removeFromUrlbar.label "Remove from Address Bar">
<!ENTITY pageAction.allowInUrlbar.label "Show in Address Bar">
<!ENTITY pageAction.disallowInUrlbar.label "Don’t Show in Address Bar">
<!ENTITY pageAction.manageExtension.label "Manage Extension…">
<!ENTITY pageAction.sendTabToDevice.label "Send Tab to Device">
<!ENTITY sendToDevice.syncNotReady.label "Syncing Devices…">
+<!ENTITY pageAction.shareUrl.label "Share">
+
<!ENTITY libraryButton.tooltip "View history, saved bookmarks, and more">
<!-- LOCALIZATION NOTE: (accessibilityIndicator.tooltip): This is used to
display a tooltip for accessibility indicator in toolbar/tabbar. It is also
used as a textual label for the indicator used by assistive technology
users. -->
<!ENTITY accessibilityIndicator.tooltip "Accessibility Features Enabled">
--- a/browser/modules/PageActions.jsm
+++ b/browser/modules/PageActions.jsm
@@ -1162,16 +1162,35 @@ if (Services.prefs.getBoolPref("identity
},
onSubviewShowing(panelViewNode) {
browserPageActions(panelViewNode).sendToDevice
.onShowingSubview(panelViewNode);
},
});
}
+if (AppConstants.platform == "macosx") {
+ gBuiltInActions.push(
+ // Share URL
+ {
+ id: "shareURL",
+ title: "shareURL-title",
+ onShowingInPanel(buttonNode) {
+ browserPageActions(buttonNode).shareURL.onShowingInPanel(buttonNode);
+ },
+ onPlacedInPanel(buttonNode) {
+ browserPageActions(buttonNode).shareURL.onPlacedInPanel(buttonNode);
+ },
+ wantsSubview: true,
+ onSubviewShowing(panelViewNode) {
+ browserPageActions(panelViewNode).shareURL
+ .onShowingSubview(panelViewNode);
+ },
+ });
+}
/**
* Gets a BrowserPageActions object in a browser window.
*
* @param obj
* Either a DOM node or a browser window.
* @return The BrowserPageActions object in the browser window related to the
* given object.
--- a/browser/themes/osx/browser.css
+++ b/browser/themes/osx/browser.css
@@ -330,16 +330,20 @@ html|input.urlbar-input {
}
.urlbar-display {
margin-top: 0;
margin-bottom: 0;
color: GrayText;
}
+#pageAction-panel-shareURL {
+ list-style-image: url("chrome://browser/skin/share.svg");
+}
+
%include ../shared/urlbarSearchSuggestionsNotification.inc.css
/* ----- AUTOCOMPLETE ----- */
%include ../shared/autocomplete.inc.css
%include ../shared/urlbar-autocomplete.inc.css
:root {
--- a/browser/themes/osx/jar.mn
+++ b/browser/themes/osx/jar.mn
@@ -51,16 +51,17 @@ browser.jar:
skin/classic/browser/places/livemark-item.png (places/livemark-item.png)
skin/classic/browser/preferences/alwaysAsk.png (preferences/alwaysAsk.png)
skin/classic/browser/preferences/application.png (preferences/application.png)
skin/classic/browser/preferences/saveFile.png (preferences/saveFile.png)
* skin/classic/browser/preferences/preferences.css (preferences/preferences.css)
* skin/classic/browser/preferences/in-content/preferences.css (preferences/in-content/preferences.css)
* skin/classic/browser/preferences/in-content/dialog.css (preferences/in-content/dialog.css)
skin/classic/browser/preferences/applications.css (preferences/applications.css)
+ skin/classic/browser/share.svg (share.svg)
skin/classic/browser/tabbrowser/tabDragIndicator.png (tabbrowser/tabDragIndicator.png)
skin/classic/browser/tabbrowser/tabDragIndicator@2x.png (tabbrowser/tabDragIndicator@2x.png)
skin/classic/browser/e10s-64@2x.png (../shared/e10s-64@2x.png)
[extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}] chrome.jar:
% override chrome://browser/skin/feeds/audioFeedIcon.png chrome://browser/skin/feeds/feedIcon.png
% override chrome://browser/skin/feeds/audioFeedIcon16.png chrome://browser/skin/feeds/feedIcon16.png
% override chrome://browser/skin/feeds/videoFeedIcon.png chrome://browser/skin/feeds/feedIcon.png
new file mode 100644
--- /dev/null
+++ b/browser/themes/osx/share.svg
@@ -0,0 +1,7 @@
+<!-- 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/. -->
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
+ <path fill="context-fill" d="M12.707 4.294l-4-4A1 1 0 0 0 8.38.077a.984.984 0 0 0-.246-.05A.938.938 0 0 0 8 0a.938.938 0 0 0-.134.027.984.984 0 0 0-.246.05A1 1 0 0 0 7.291.3l-4 4a1 1 0 0 0 1.416 1.408L7 3.415V11a1 1 0 0 0 2 0V3.415l2.293 2.293a1 1 0 0 0 1.414-1.414z"></path>
+ <path fill="context-fill" d="M14 9a1 1 0 0 0-1 1v3a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1v-3a1 1 0 0 0-2 0v3a3 3 0 0 0 3 3h8a3 3 0 0 0 3-3v-3a1 1 0 0 0-1-1z"></path>
+</svg>
--- a/widget/cocoa/moz.build
+++ b/widget/cocoa/moz.build
@@ -34,16 +34,17 @@ UNIFIED_SOURCES += [
'nsColorPicker.mm',
'nsCursorManager.mm',
'nsDeviceContextSpecX.mm',
'nsFilePicker.mm',
'nsIdleServiceX.mm',
'nsLookAndFeel.mm',
'nsMacCursor.mm',
'nsMacDockSupport.mm',
+ 'nsMacSharingService.mm',
'nsMacWebAppUtils.mm',
'nsMenuBarX.mm',
'nsMenuGroupOwnerX.mm',
'nsMenuItemIconX.mm',
'nsMenuItemX.mm',
'nsMenuUtilsX.mm',
'nsMenuX.mm',
'nsPrintDialogX.mm',
new file mode 100644
--- /dev/null
+++ b/widget/cocoa/nsMacSharingService.h
@@ -0,0 +1,23 @@
+/* -*- Mode: c++; tab-width: 2; indent-tabs-mode: nil; -*- */
+/* 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 nsMacSharingService_h_
+#define nsMacSharingService_h_
+
+#include "nsIMacSharingService.h"
+
+class nsMacSharingService : public nsIMacSharingService
+{
+public:
+ nsMacSharingService() {}
+
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIMACSHARINGSERVICE
+
+protected:
+ virtual ~nsMacSharingService() {}
+};
+
+#endif // nsMacSharingService_h_
new file mode 100644
--- /dev/null
+++ b/widget/cocoa/nsMacSharingService.mm
@@ -0,0 +1,92 @@
+/* -*- Mode: c++; tab-width: 2; indent-tabs-mode: nil; -*- */
+/* 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/. */
+
+#import <Cocoa/Cocoa.h>
+
+#include "nsMacSharingService.h"
+#include "nsCocoaUtils.h"
+#include "mozilla/MacStringHelpers.h"
+
+NS_IMPL_ISUPPORTS(nsMacSharingService, nsIMacSharingService)
+
+static NSString*
+NSImageToBase64(const NSImage* aImage)
+{
+ [aImage lockFocus];
+ NSBitmapImageRep* bitmapRep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:NSMakeRect(0, 0, aImage.size.width, aImage.size.height)];
+ [aImage unlockFocus];
+ NSData* imageData = [bitmapRep representationUsingType:NSPNGFileType properties:@{}];
+ [bitmapRep release];
+ NSString* base64Encoded = [imageData base64EncodedStringWithOptions:0];
+ return [NSString stringWithFormat: @"data:image/png;base64,%@", base64Encoded];
+}
+
+static void
+SetStrAttribute(JSContext* aCx,
+ JS::Rooted<JSObject*>& aObj,
+ const char* aKey, NSString* aVal)
+{
+ nsAutoString strVal;
+ mozilla::CopyCocoaStringToXPCOMString(aVal, strVal);
+ JS::Rooted<JSString*> title(aCx, JS_NewUCStringCopyZ(aCx, strVal.get()));
+ JS::Rooted<JS::Value> attVal(aCx, JS::StringValue(title));
+ JS_SetProperty(aCx, aObj, aKey, attVal);
+}
+
+nsresult
+nsMacSharingService::GetSharingProviders(const nsAString& aUrlToShare,
+ JSContext* aCx,
+ JS::MutableHandleValue aResult)
+{
+ NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
+
+ JS::Rooted<JSObject*> array(aCx, JS_NewArrayObject(aCx, 0));
+ NSURL* url = [NSURL URLWithString:nsCocoaUtils::ToNSString(aUrlToShare)];
+
+ NSArray* sharingService = [NSSharingService
+ sharingServicesForItems:[NSArray arrayWithObject:url]];
+ int32_t serviceCount = 0;
+
+ for (NSSharingService *currentService in sharingService) {
+
+ JS::Rooted<JSObject*> obj(aCx, JS_NewPlainObject(aCx));
+
+ SetStrAttribute(aCx, obj, "title", currentService.title);
+ SetStrAttribute(aCx, obj, "menuItemTitle", currentService.menuItemTitle);
+ SetStrAttribute(aCx, obj, "image", NSImageToBase64(currentService.image));
+
+ JS::Rooted<JS::Value> element(aCx, JS::ObjectValue(*obj));
+ JS_SetElement(aCx, array, serviceCount++, element);
+ }
+
+ aResult.setObject(*array);
+
+ return NS_OK;
+ NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
+}
+
+NS_IMETHODIMP
+nsMacSharingService::ShareUrl(const nsAString& aShareTitle,
+ const nsAString& aUrlToShare)
+{
+ NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
+
+ NSString* titleString = nsCocoaUtils::ToNSString(aShareTitle);
+ NSURL* url = [NSURL URLWithString:nsCocoaUtils::ToNSString(aUrlToShare)];
+
+ NSArray* sharingService = [NSSharingService
+ sharingServicesForItems:[NSArray arrayWithObject:url]];
+
+ for (NSSharingService *currentService in sharingService) {
+ if ([currentService.title isEqualToString:titleString]) {
+ [currentService performWithItems:@[url]];
+ break;
+ }
+ }
+
+ return NS_OK;
+
+ NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
+}
--- a/widget/cocoa/nsPrintDialogX.mm
+++ b/widget/cocoa/nsPrintDialogX.mm
@@ -1,14 +1,15 @@
/* -*- 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 "mozilla/ArrayUtils.h"
+#include "mozilla/gfx/PrintTargetCG.h"
#include "mozilla/Preferences.h"
#include "nsPrintDialogX.h"
#include "nsIPrintSettings.h"
#include "nsIPrintSettingsService.h"
#include "nsPrintSettingsX.h"
#include "nsCOMPtr.h"
#include "nsQueryObject.h"
@@ -17,16 +18,17 @@
#include "nsIStringBundle.h"
#include "nsIWebBrowserPrint.h"
#include "nsCRT.h"
#import <Cocoa/Cocoa.h>
#include "nsObjCExceptions.h"
using namespace mozilla;
+using mozilla::gfx::PrintTarget;
NS_IMPL_ISUPPORTS(nsPrintDialogServiceX, nsIPrintDialogService)
nsPrintDialogServiceX::nsPrintDialogServiceX()
{
}
nsPrintDialogServiceX::~nsPrintDialogServiceX()
--- a/widget/cocoa/nsWidgetFactory.mm
+++ b/widget/cocoa/nsWidgetFactory.mm
@@ -89,16 +89,19 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsNativeM
NS_GENERIC_FACTORY_CONSTRUCTOR(nsBidiKeyboard)
#include "nsNativeThemeCocoa.h"
NS_GENERIC_FACTORY_CONSTRUCTOR(nsNativeThemeCocoa)
#include "nsMacDockSupport.h"
NS_GENERIC_FACTORY_CONSTRUCTOR(nsMacDockSupport)
+#include "nsMacSharingService.h"
+NS_GENERIC_FACTORY_CONSTRUCTOR(nsMacSharingService)
+
#include "nsMacWebAppUtils.h"
NS_GENERIC_FACTORY_CONSTRUCTOR(nsMacWebAppUtils)
#include "nsStandaloneNativeMenu.h"
NS_GENERIC_FACTORY_CONSTRUCTOR(nsStandaloneNativeMenu)
#include "nsSystemStatusBarCocoa.h"
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSystemStatusBarCocoa)
@@ -129,16 +132,17 @@ NS_DEFINE_NAMED_CID(NS_SCREENMANAGER_CID
NS_DEFINE_NAMED_CID(NS_DEVICE_CONTEXT_SPEC_CID);
NS_DEFINE_NAMED_CID(NS_PRINTSESSION_CID);
NS_DEFINE_NAMED_CID(NS_PRINTSETTINGSSERVICE_CID);
NS_DEFINE_NAMED_CID(NS_PRINTDIALOGSERVICE_CID);
NS_DEFINE_NAMED_CID(NS_IDLE_SERVICE_CID);
NS_DEFINE_NAMED_CID(NS_SYSTEMALERTSSERVICE_CID);
NS_DEFINE_NAMED_CID(NS_NATIVEMENUSERVICE_CID);
NS_DEFINE_NAMED_CID(NS_MACDOCKSUPPORT_CID);
+NS_DEFINE_NAMED_CID(NS_MACSHARINGSERVICE_CID);
NS_DEFINE_NAMED_CID(NS_MACWEBAPPUTILS_CID);
NS_DEFINE_NAMED_CID(NS_STANDALONENATIVEMENU_CID);
NS_DEFINE_NAMED_CID(NS_MACSYSTEMSTATUSBAR_CID);
NS_DEFINE_NAMED_CID(NS_GFXINFO_CID);
static const mozilla::Module::CIDEntry kWidgetCIDs[] = {
{ &kNS_WINDOW_CID, false, NULL, nsCocoaWindowConstructor },
{ &kNS_POPUP_CID, false, NULL, nsCocoaWindowConstructor },
@@ -165,16 +169,17 @@ static const mozilla::Module::CIDEntry k
{ &kNS_DEVICE_CONTEXT_SPEC_CID, false, NULL, nsDeviceContextSpecXConstructor },
{ &kNS_PRINTSESSION_CID, false, NULL, nsPrintSessionConstructor },
{ &kNS_PRINTSETTINGSSERVICE_CID, false, NULL, nsPrintSettingsServiceXConstructor },
{ &kNS_PRINTDIALOGSERVICE_CID, false, NULL, nsPrintDialogServiceXConstructor },
{ &kNS_IDLE_SERVICE_CID, false, NULL, nsIdleServiceXConstructor },
{ &kNS_SYSTEMALERTSSERVICE_CID, false, NULL, OSXNotificationCenterConstructor },
{ &kNS_NATIVEMENUSERVICE_CID, false, NULL, nsNativeMenuServiceXConstructor },
{ &kNS_MACDOCKSUPPORT_CID, false, NULL, nsMacDockSupportConstructor },
+ { &kNS_MACSHARINGSERVICE_CID, false, NULL, nsMacSharingServiceConstructor },
{ &kNS_MACWEBAPPUTILS_CID, false, NULL, nsMacWebAppUtilsConstructor },
{ &kNS_STANDALONENATIVEMENU_CID, false, NULL, nsStandaloneNativeMenuConstructor },
{ &kNS_MACSYSTEMSTATUSBAR_CID, false, NULL, nsSystemStatusBarCocoaConstructor },
{ &kNS_GFXINFO_CID, false, NULL, mozilla::widget::GfxInfoConstructor },
{ NULL }
};
static const mozilla::Module::ContractIDEntry kWidgetContracts[] = {
@@ -203,16 +208,17 @@ static const mozilla::Module::ContractID
{ "@mozilla.org/gfx/devicecontextspec;1", &kNS_DEVICE_CONTEXT_SPEC_CID },
{ "@mozilla.org/gfx/printsession;1", &kNS_PRINTSESSION_CID },
{ "@mozilla.org/gfx/printsettings-service;1", &kNS_PRINTSETTINGSSERVICE_CID },
{ NS_PRINTDIALOGSERVICE_CONTRACTID, &kNS_PRINTDIALOGSERVICE_CID },
{ "@mozilla.org/widget/idleservice;1", &kNS_IDLE_SERVICE_CID },
{ "@mozilla.org/system-alerts-service;1", &kNS_SYSTEMALERTSSERVICE_CID },
{ "@mozilla.org/widget/nativemenuservice;1", &kNS_NATIVEMENUSERVICE_CID },
{ "@mozilla.org/widget/macdocksupport;1", &kNS_MACDOCKSUPPORT_CID },
+ { "@mozilla.org/widget/macsharingservice;1", &kNS_MACSHARINGSERVICE_CID },
{ "@mozilla.org/widget/mac-web-app-utils;1", &kNS_MACWEBAPPUTILS_CID },
{ "@mozilla.org/widget/standalonenativemenu;1", &kNS_STANDALONENATIVEMENU_CID },
{ "@mozilla.org/widget/macsystemstatusbar;1", &kNS_MACSYSTEMSTATUSBAR_CID },
{ "@mozilla.org/gfx/info;1", &kNS_GFXINFO_CID },
{ NULL }
};
static void
--- a/widget/moz.build
+++ b/widget/moz.build
@@ -54,16 +54,17 @@ if toolkit == 'windows':
'nsITaskbarTabPreview.idl',
'nsITaskbarWindowPreview.idl',
'nsIWindowsUIUtils.idl',
'nsIWinTaskbar.idl',
]
elif toolkit == 'cocoa':
XPIDL_SOURCES += [
'nsIMacDockSupport.idl',
+ 'nsIMacSharingService.idl',
'nsIMacWebAppUtils.idl',
'nsIStandaloneNativeMenu.idl',
'nsISystemStatusBar.idl',
'nsITaskbarProgress.idl',
]
EXPORTS += [
'nsINativeMenuService.h',
]
new file mode 100644
--- /dev/null
+++ b/widget/nsIMacSharingService.idl
@@ -0,0 +1,23 @@
+/* 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 "nsISupports.idl"
+
+/**
+ * Allow applications to interface with the Mac OS X Sharing APIs.
+ */
+
+[scriptable, uuid(de59fe1a-46c8-490f-b04d-34545acb06c9)]
+interface nsIMacSharingService : nsISupports
+{
+ /**
+ * Get list of sharing providers
+ */
+ [implicit_jscontext] jsval getSharingProviders(in AString urlToShare);
+
+ /**
+ * Launch service with shareTitle with given url
+ */
+ void shareUrl(in AString shareTitle, in AString urlToShare);
+};
--- a/widget/nsWidgetsCID.h
+++ b/widget/nsWidgetsCID.h
@@ -70,16 +70,21 @@
{ 0x1F39AE50, 0xB6A0, 0x4B37, \
{ 0x90, 0xF4, 0x60, 0xAF, 0x61, 0x41, 0x93, 0xD8 }}
// {2451BAED-8DC3-46D9-9E30-96E1BAA03666}
#define NS_MACDOCKSUPPORT_CID \
{ 0x2451BAED, 0x8DC3, 0x46D9, \
{ 0x9E, 0x30, 0x96, 0xE1, 0xBA, 0xA0, 0x36, 0x66 } }
+// {de59fe1a-46c8-490f-b04d-34545acb06c9}
+#define NS_MACSHARINGSERVICE_CID \
+{ 0xde59fe1a, 0x46c8, 0x490f, \
+ { 0xb0, 0x4d, 0x34, 0x54, 0x5a, 0xcb, 0x06, 0xc9 } }
+
// {b6e1a890-b2b8-4883-a65f-9476f6185313}
#define NS_MACSYSTEMSTATUSBAR_CID \
{ 0xb6e1a890, 0xb2b8, 0x4883, \
{ 0xa6, 0x5f, 0x94, 0x76, 0xf6, 0x18, 0x53, 0x13 } }
//-----------------------------------------------------------
//Drag & Drop & Clipboard
//-----------------------------------------------------------
new file mode 100644
--- /dev/null
+++ b/widget/tests/unit/test_macsharingservice.js
@@ -0,0 +1,27 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 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/. */
+
+//Basic tests to verify that MacSharingService returns expected data
+
+ChromeUtils.import("resource://gre/modules/Services.jsm");
+ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
+
+function test_getSharingProviders()
+{
+ let sharingService = Cc["@mozilla.org/widget/macsharingservice;1"].
+ getService(Ci.nsIMacSharingService);
+ let providers = sharingService.getSharingProviders("http://example.org");
+ Assert.ok(providers.length > 1, "There are providers returned");
+ providers.forEach(provider => {
+ Assert.ok("title" in provider, "Provider has title");
+ Assert.ok("menuItemTitle" in provider, "Provider has menuItemTitle");
+ Assert.ok("image" in provider, "Provider has image");
+ });
+}
+
+function run_test()
+{
+ test_getSharingProviders();
+}
--- a/widget/tests/unit/xpcshell.ini
+++ b/widget/tests/unit/xpcshell.ini
@@ -1,6 +1,8 @@
[DEFAULT]
head =
[test_taskbar_jumplistitems.js]
+[test_macsharingservice.js]
+skip-if = os != "mac"
[test_macwebapputils.js]
skip-if = os != "mac"