зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to mozilla-inbound. a=merge on a CLOSED TREE
This commit is contained in:
Коммит
c39d5dafe5
|
@ -1288,14 +1288,16 @@ BrowserPageActions.shareURL = {
|
|||
shareProviders.forEach(function(share) {
|
||||
let item = document.createElement("toolbarbutton");
|
||||
item.setAttribute("label", share.menuItemTitle);
|
||||
item.setAttribute("share-title", share.title);
|
||||
item.setAttribute("share-name", share.name);
|
||||
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);
|
||||
let shareName = event.target.getAttribute("share-name");
|
||||
if (shareName) {
|
||||
sharingService.shareUrl(shareName,
|
||||
currentURI,
|
||||
gBrowser.selectedBrowser.contentTitle);
|
||||
}
|
||||
PanelMultiView.hidePopup(BrowserPageActions.panelNode);
|
||||
});
|
||||
|
|
|
@ -10,11 +10,12 @@ Services.scriptloader.loadSubScript("resource://testing-common/sinon-2.3.2.js");
|
|||
const URL = "http://example.org/";
|
||||
|
||||
// Keep track of title of service we chose to share with
|
||||
let sharedTitle;
|
||||
let serviceName;
|
||||
let sharedUrl;
|
||||
let sharedTitle;
|
||||
|
||||
let mockShareData = [{
|
||||
title: "NSA",
|
||||
name: "NSA",
|
||||
menuItemTitle: "National Security Agency",
|
||||
image: "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEA" +
|
||||
"LAAAAAABAAEAAAICTAEAOw=="
|
||||
|
@ -25,7 +26,8 @@ let stub = sinon.stub(BrowserPageActions.shareURL, "_sharingService").get(() =>
|
|||
getSharingProviders(url) {
|
||||
return mockShareData;
|
||||
},
|
||||
shareUrl(title, url) {
|
||||
shareUrl(name, url, title) {
|
||||
serviceName = name;
|
||||
sharedUrl = url;
|
||||
sharedTitle = title;
|
||||
}
|
||||
|
@ -61,10 +63,12 @@ add_task(async function shareURL() {
|
|||
EventUtils.synthesizeMouseAtCenter(shareButton, {});
|
||||
await hiddenPromise;
|
||||
|
||||
Assert.equal(sharedTitle, mockShareData[0].title,
|
||||
"Shared with the correct title");
|
||||
Assert.equal(serviceName, mockShareData[0].name,
|
||||
"Shared the correct service name");
|
||||
Assert.equal(sharedUrl, "http://example.org/",
|
||||
"Shared correct URL");
|
||||
Assert.equal(sharedTitle, "mochitest index /",
|
||||
"Shared with the correct title");
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -1169,21 +1169,21 @@ var interfaceNamesInGlobalScope =
|
|||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "VideoStreamTrack", insecureContext: true},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "VRDisplay", insecureContext: true, releaseNonWindowsAndMac: false},
|
||||
{name: "VRDisplay", insecureContext: true, releaseNonWindows: false},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "VRDisplayCapabilities", insecureContext: true, releaseNonWindowsAndMac: false},
|
||||
{name: "VRDisplayCapabilities", insecureContext: true, releaseNonWindows: false},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "VRDisplayEvent", insecureContext: true, releaseNonWindowsAndMac: false},
|
||||
{name: "VRDisplayEvent", insecureContext: true, releaseNonWindows: false},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "VREyeParameters", insecureContext: true, releaseNonWindowsAndMac: false},
|
||||
{name: "VREyeParameters", insecureContext: true, releaseNonWindows: false},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "VRFieldOfView", insecureContext: true, releaseNonWindowsAndMac: false},
|
||||
{name: "VRFieldOfView", insecureContext: true, releaseNonWindows: false},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "VRFrameData", insecureContext: true, releaseNonWindowsAndMac: false},
|
||||
{name: "VRFrameData", insecureContext: true, releaseNonWindows: false},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "VRPose", insecureContext: true, releaseNonWindowsAndMac: false},
|
||||
{name: "VRPose", insecureContext: true, releaseNonWindows: false},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "VRStageParameters", insecureContext: true, releaseNonWindowsAndMac: false},
|
||||
{name: "VRStageParameters", insecureContext: true, releaseNonWindows: false},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "VTTCue", insecureContext: true},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
|
@ -1291,7 +1291,7 @@ function createInterfaceMap(isXBLScope) {
|
|||
(entry.linux === !isLinux) ||
|
||||
(entry.android === !isAndroid && !entry.nightlyAndroid) ||
|
||||
(entry.release === !isRelease) ||
|
||||
(entry.releaseNonWindowsAndMac === !(isRelease && !isWindows && !isMac)) ||
|
||||
(entry.releaseNonWindows === !(isRelease && !isWindows)) ||
|
||||
// The insecureContext test is very purposefully converting
|
||||
// entry.insecureContext to boolean, so undefined will convert to
|
||||
// false. That way entries without an insecureContext annotation
|
||||
|
|
|
@ -317,18 +317,14 @@ gfxFT2FontBase::InitMetrics()
|
|||
// If the OS/2 fsSelection USE_TYPO_METRICS bit is set,
|
||||
// set maxAscent/Descent from the sTypo* fields instead of hhea.
|
||||
const uint16_t kUseTypoMetricsMask = 1 << 7;
|
||||
if (os2->fsSelection & kUseTypoMetricsMask) {
|
||||
mMetrics.maxAscent = NS_round(mMetrics.emAscent);
|
||||
mMetrics.maxDescent = NS_round(mMetrics.emDescent);
|
||||
} else {
|
||||
if ((os2->fsSelection & kUseTypoMetricsMask) ||
|
||||
// maxAscent/maxDescent get used for frame heights, and some fonts
|
||||
// don't have the HHEA table ascent/descent set (bug 279032).
|
||||
(mMetrics.maxAscent == 0.0 && mMetrics.maxDescent == 0.0)) {
|
||||
// We use NS_round here to parallel the pixel-rounded values that
|
||||
// freetype gives us for ftMetrics.ascender/descender.
|
||||
mMetrics.maxAscent =
|
||||
std::max(mMetrics.maxAscent, NS_round(mMetrics.emAscent));
|
||||
mMetrics.maxDescent =
|
||||
std::max(mMetrics.maxDescent, NS_round(mMetrics.emDescent));
|
||||
mMetrics.maxAscent = NS_round(mMetrics.emAscent);
|
||||
mMetrics.maxDescent = NS_round(mMetrics.emDescent);
|
||||
}
|
||||
} else {
|
||||
mMetrics.emAscent = mMetrics.maxAscent;
|
||||
|
|
|
@ -129,7 +129,7 @@ load 486974-1.html
|
|||
# Tests for bug 523717
|
||||
== underline-offset-change-1.html underline-offset-change-1-ref.html
|
||||
== underline-offset-change-2.html underline-offset-change-2-ref.html
|
||||
fails-if(cocoaWidget||winWidget) != underline-offset-change-1-ref.html underline-offset-change-2-ref.html # Bug 534132
|
||||
fails != underline-offset-change-1-ref.html underline-offset-change-2-ref.html # Bug 534132
|
||||
|
||||
!= 534352-1-extra-cmap-sentinel.html 534352-1-extra-cmap-sentinel-ref.html
|
||||
== bug533251.html bug533251-ref.html
|
||||
|
|
|
@ -5142,7 +5142,7 @@ pref("dom.placeholder.show_on_focus", true);
|
|||
|
||||
// WebVR is enabled by default in beta and release for Windows and for all
|
||||
// platforms in nightly and aurora.
|
||||
#if defined(XP_WIN) || defined(XP_MACOSX) || !defined(RELEASE_OR_BETA)
|
||||
#if defined(XP_WIN) || !defined(RELEASE_OR_BETA)
|
||||
pref("dom.vr.enabled", true);
|
||||
#else
|
||||
pref("dom.vr.enabled", false);
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
[padding-em-inherit-001.xht]
|
||||
expected: FAIL
|
|
@ -9,12 +9,66 @@
|
|||
#include "nsCocoaUtils.h"
|
||||
#include "mozilla/MacStringHelpers.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsMacSharingService, nsIMacSharingService)
|
||||
|
||||
// List of sharingProviders that we do not want to expose to
|
||||
// the user, because they are duplicates or do not work correctly
|
||||
// within the context
|
||||
NSArray *filteredProviderTitles = @[@"Add to Reading List", @"Mail"];
|
||||
NSArray *filteredProviderNames = @[
|
||||
@"com.apple.share.System.add-to-safari-reading-list",
|
||||
@"com.apple.share.Mail.compose"
|
||||
];
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsMacSharingService, nsIMacSharingService)
|
||||
NSString* const remindersServiceName =
|
||||
@"com.apple.reminders.RemindersShareExtension";
|
||||
|
||||
// Expose the id so we can pass reference through to JS and back
|
||||
@interface NSSharingService (ExposeName)
|
||||
- (id)name;
|
||||
@end
|
||||
|
||||
// Clean up the activity once the share is complete
|
||||
@interface SharingServiceDelegate : NSObject <NSSharingServiceDelegate>
|
||||
{
|
||||
NSUserActivity* mShareActivity;
|
||||
}
|
||||
|
||||
- (void)cleanup;
|
||||
|
||||
@end
|
||||
|
||||
@implementation SharingServiceDelegate
|
||||
|
||||
- (id)initWithActivity:(NSUserActivity*)activity
|
||||
{
|
||||
self = [super init];
|
||||
mShareActivity = [activity retain];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)cleanup {
|
||||
[mShareActivity resignCurrent];
|
||||
[mShareActivity invalidate];
|
||||
[mShareActivity release];
|
||||
mShareActivity = nil;
|
||||
}
|
||||
|
||||
- (void)sharingService:(NSSharingService *)sharingService
|
||||
didShareItems:(NSArray *)items {
|
||||
[self cleanup];
|
||||
}
|
||||
|
||||
- (void)sharingService:(NSSharingService*)service
|
||||
didFailToShareItems:(NSArray*)items error:(NSError*)error {
|
||||
[self cleanup];
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[mShareActivity release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
static NSString*
|
||||
NSImageToBase64(const NSImage* aImage)
|
||||
|
@ -41,30 +95,31 @@ SetStrAttribute(JSContext* aCx,
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsMacSharingService::GetSharingProviders(const nsAString& aUrlToShare,
|
||||
nsMacSharingService::GetSharingProviders(const nsAString& aPageUrl,
|
||||
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)];
|
||||
NSURL* url = [NSURL URLWithString:nsCocoaUtils::ToNSString(aPageUrl)];
|
||||
|
||||
NSArray* sharingService = [NSSharingService
|
||||
sharingServicesForItems:[NSArray arrayWithObject:url]];
|
||||
int32_t serviceCount = 0;
|
||||
|
||||
for (NSSharingService *currentService in sharingService) {
|
||||
if (![filteredProviderTitles containsObject:currentService.title]) {
|
||||
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);
|
||||
if ([filteredProviderNames containsObject:[currentService name]]) {
|
||||
continue;
|
||||
}
|
||||
JS::Rooted<JSObject*> obj(aCx, JS_NewPlainObject(aCx));
|
||||
|
||||
SetStrAttribute(aCx, obj, "name", [currentService name]);
|
||||
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);
|
||||
|
@ -74,24 +129,48 @@ nsMacSharingService::GetSharingProviders(const nsAString& aUrlToShare,
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMacSharingService::ShareUrl(const nsAString& aShareTitle,
|
||||
const nsAString& aUrlToShare)
|
||||
nsMacSharingService::ShareUrl(const nsAString& aServiceName,
|
||||
const nsAString& aPageUrl,
|
||||
const nsAString& aPageTitle)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
NSString* titleString = nsCocoaUtils::ToNSString(aShareTitle);
|
||||
NSURL* url = [NSURL URLWithString:nsCocoaUtils::ToNSString(aUrlToShare)];
|
||||
NSString* serviceName = nsCocoaUtils::ToNSString(aServiceName);
|
||||
NSURL* pageUrl = [NSURL URLWithString:nsCocoaUtils::ToNSString(aPageUrl)];
|
||||
NSString* pageTitle = nsCocoaUtils::ToNSString(aPageTitle);
|
||||
NSSharingService* service = [NSSharingService
|
||||
sharingServiceNamed:serviceName];
|
||||
|
||||
NSArray* sharingService = [NSSharingService
|
||||
sharingServicesForItems:[NSArray arrayWithObject:url]];
|
||||
// Reminders fetch its data from an activity, not the share data
|
||||
if ([[service name] isEqual:remindersServiceName]) {
|
||||
|
||||
for (NSSharingService *currentService in sharingService) {
|
||||
if ([currentService.title isEqualToString:titleString]) {
|
||||
[currentService performWithItems:@[url]];
|
||||
break;
|
||||
NSUserActivity* shareActivity =
|
||||
[[NSUserActivity alloc] initWithActivityType:NSUserActivityTypeBrowsingWeb];
|
||||
|
||||
if ([pageUrl.scheme hasPrefix:@"http"]) {
|
||||
[shareActivity setWebpageURL:pageUrl];
|
||||
}
|
||||
[shareActivity setTitle:pageTitle];
|
||||
[shareActivity becomeCurrent];
|
||||
|
||||
// Pass ownership of shareActivity to shareDelegate, which will release the
|
||||
// activity once sharing has completed.
|
||||
SharingServiceDelegate* shareDelegate =
|
||||
[[SharingServiceDelegate alloc] initWithActivity:shareActivity];
|
||||
[shareActivity release];
|
||||
|
||||
[service setDelegate:shareDelegate];
|
||||
[shareDelegate release];
|
||||
}
|
||||
|
||||
// Twitter likes the the title as an additional share item
|
||||
NSArray* toShare = [[service name] isEqual:NSSharingServiceNamePostOnTwitter]
|
||||
? @[pageUrl, pageTitle]
|
||||
: @[pageUrl];
|
||||
|
||||
[service setSubject:pageTitle];
|
||||
[service performWithItems:toShare];
|
||||
|
||||
return NS_OK;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
|
|
@ -14,10 +14,12 @@ interface nsIMacSharingService : nsISupports
|
|||
/**
|
||||
* Get list of sharing providers
|
||||
*/
|
||||
[implicit_jscontext] jsval getSharingProviders(in AString urlToShare);
|
||||
[implicit_jscontext] jsval getSharingProviders(in AString pageUrl);
|
||||
|
||||
/**
|
||||
* Launch service with shareTitle with given url
|
||||
*/
|
||||
void shareUrl(in AString shareTitle, in AString urlToShare);
|
||||
void shareUrl(in AString serviceName,
|
||||
in AString pageUrl,
|
||||
in AString pageTitle);
|
||||
};
|
||||
|
|
|
@ -15,7 +15,7 @@ function test_getSharingProviders()
|
|||
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("name" in provider, "Provider has name");
|
||||
Assert.ok("menuItemTitle" in provider, "Provider has menuItemTitle");
|
||||
Assert.ok("image" in provider, "Provider has image");
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче