зеркало из https://github.com/mozilla/gecko-dev.git
Merge autoland to central, a=merge
MozReview-Commit-ID: Fv1T41t9Gof
This commit is contained in:
Коммит
9aa04a95f3
|
@ -13,7 +13,7 @@ support-files =
|
|||
[browser_shutdown_parent_own_reference.js]
|
||||
skip-if = !e10s || (os == 'win' && os_version == '5.1') # e10s specific test for a11y start/shutdown between parent and content.
|
||||
[browser_shutdown_proxy_acc_reference.js]
|
||||
skip-if = !e10s || (os == 'win') # e10s specific test for a11y start/shutdown between parent and content.
|
||||
skip-if = !e10s || (os == 'win') || stylo # e10s specific test for a11y start/shutdown between parent and content. bug 1390409 for stylo
|
||||
[browser_shutdown_proxy_doc_acc_reference.js]
|
||||
skip-if = !e10s || (os == 'win') # e10s specific test for a11y start/shutdown between parent and content.
|
||||
[browser_shutdown_multi_proxy_acc_reference_doc.js]
|
||||
|
|
|
@ -26,7 +26,9 @@ skip-if = e10s && os == 'win' && debug # Bug 1338034, leaks
|
|||
# Events tests
|
||||
[browser_events_caretmove.js]
|
||||
[browser_events_hide.js]
|
||||
skip-if = stylo # bug 1390409
|
||||
[browser_events_show.js]
|
||||
skip-if = stylo # bug 1390409
|
||||
[browser_events_statechange.js]
|
||||
[browser_events_textchange.js]
|
||||
|
||||
|
@ -48,5 +50,6 @@ skip-if = e10s && os == 'win' # Bug 1288839
|
|||
[browser_treeupdate_table.js]
|
||||
[browser_treeupdate_textleaf.js]
|
||||
[browser_treeupdate_visibility.js]
|
||||
skip-if = stylo # bug 1390409
|
||||
[browser_treeupdate_whitespace.js]
|
||||
skip-if = true # Failing due to incorrect index of test container children on document load.
|
||||
|
|
|
@ -1313,11 +1313,6 @@ pref("image.mem.max_decoded_image_kb", 256000);
|
|||
// Is the sidebar positioned ahead of the content browser
|
||||
pref("sidebar.position_start", true);
|
||||
|
||||
// Activation from inside of share panel is possible if activationPanelEnabled
|
||||
// is true. Pref'd off for release while usage testing is done through beta.
|
||||
pref("social.share.activationPanelEnabled", true);
|
||||
pref("social.shareDirectory", "https://activations.cdn.mozilla.net/sharePanel.html");
|
||||
|
||||
// Block insecure active content on https pages
|
||||
pref("security.mixed_content.block_active_content", true);
|
||||
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!-- 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/. -->
|
||||
|
||||
<!DOCTYPE html [
|
||||
<!ENTITY % htmlDTD
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"DTD/xhtml1-strict.dtd">
|
||||
%htmlDTD;
|
||||
<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd" >
|
||||
%brandDTD;
|
||||
<!ENTITY % browserDTD SYSTEM "chrome://browser/locale/browser.dtd">
|
||||
%browserDTD;
|
||||
]>
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>&social.directory.label;</title>
|
||||
<link rel="stylesheet" type="text/css" media="all"
|
||||
href="chrome://browser/skin/aboutProviderDirectory.css"/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="activation-link" hidden="true">
|
||||
<div id="message-box">
|
||||
<p>&social.directory.text;</p>
|
||||
</div>
|
||||
<div id="button-box">
|
||||
<button onclick="openDirectory()">&social.directory.button;</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="activation" hidden="true">
|
||||
<p>&social.directory.introText;</p>
|
||||
<div><iframe id="activation-frame"/></div>
|
||||
<p><a class="link" onclick="openDirectory()">&social.directory.viewmore.text;</a></p>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
<script type="text/javascript"><![CDATA[
|
||||
const Cu = Components.utils;
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
function openDirectory() {
|
||||
let url = Services.prefs.getCharPref("social.directories").split(",")[0];
|
||||
window.open(url);
|
||||
window.close();
|
||||
}
|
||||
|
||||
if (Services.prefs.getBoolPref("social.share.activationPanelEnabled")) {
|
||||
let url = Services.prefs.getCharPref("social.shareDirectory");
|
||||
document.getElementById("activation-frame").setAttribute("src", url);
|
||||
document.getElementById("activation").removeAttribute("hidden");
|
||||
} else {
|
||||
document.getElementById("activation-link").removeAttribute("hidden");
|
||||
}
|
||||
]]></script>
|
||||
</html>
|
|
@ -1,111 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!-- 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/. -->
|
||||
|
||||
<!DOCTYPE html [
|
||||
<!ENTITY % htmlDTD
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"DTD/xhtml1-strict.dtd">
|
||||
%htmlDTD;
|
||||
<!ENTITY % netErrorDTD SYSTEM "chrome://global/locale/netError.dtd">
|
||||
%netErrorDTD;
|
||||
]>
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>&loadError.label;</title>
|
||||
<link rel="stylesheet" href="chrome://browser/skin/aboutNetError.css" type="text/css" media="all" />
|
||||
<link rel="stylesheet" type="text/css" media="all" href="chrome://browser/skin/aboutSocialError.css"/>
|
||||
<link rel="icon" type="image/png" id="favicon" href="chrome://global/skin/icons/warning-16.png"/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="errorPageContainer">
|
||||
|
||||
<!-- Error Title -->
|
||||
<div id="errorTitle">
|
||||
<p id="errorShortDescText" >foo</p>
|
||||
</div>
|
||||
|
||||
<div id="button-box">
|
||||
<button id="btnTryAgain" onclick="tryAgainButton()"/>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
<script type="text/javascript"><![CDATA[
|
||||
const Cu = Components.utils;
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource:///modules/Social.jsm");
|
||||
|
||||
let config = {
|
||||
tryAgainCallback: reloadProvider
|
||||
}
|
||||
|
||||
function parseQueryString() {
|
||||
let searchParams = new URLSearchParams(document.documentURI.split("?")[1]);
|
||||
let mode = searchParams.get("mode");
|
||||
config.origin = searchParams.get("origin");
|
||||
let encodedURL = searchParams.get("url");
|
||||
let url = decodeURIComponent(encodedURL);
|
||||
// directory does not have origin set, in that case use the url origin for
|
||||
// the error message.
|
||||
if (!config.origin) {
|
||||
let URI = Services.io.newURI(url);
|
||||
config.origin =
|
||||
Services.scriptSecurityManager.createCodebasePrincipal(URI, {}).origin;
|
||||
}
|
||||
|
||||
switch (mode) {
|
||||
case "compactInfo":
|
||||
document.getElementById("btnTryAgain").style.display = "none";
|
||||
break;
|
||||
case "tryAgainOnly":
|
||||
// intentional fall-through
|
||||
case "tryAgain":
|
||||
config.tryAgainCallback = loadQueryURL;
|
||||
config.queryURL = url;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function setUpStrings() {
|
||||
let brandBundle = Services.strings.createBundle("chrome://branding/locale/brand.properties");
|
||||
let browserBundle = Services.strings.createBundle("chrome://browser/locale/browser.properties");
|
||||
|
||||
let productName = brandBundle.GetStringFromName("brandShortName");
|
||||
let provider = Social._getProviderFromOrigin(config.origin);
|
||||
let providerName = provider ? provider.name : config.origin;
|
||||
|
||||
// Sets up the error message
|
||||
let msg = browserBundle.formatStringFromName("social.error.message", [productName, providerName], 2);
|
||||
document.getElementById("errorShortDescText").textContent = msg;
|
||||
|
||||
// Sets up the buttons' labels and accesskeys
|
||||
let btnTryAgain = document.getElementById("btnTryAgain");
|
||||
btnTryAgain.textContent = browserBundle.GetStringFromName("social.error.tryAgain.label");
|
||||
btnTryAgain.accessKey = browserBundle.GetStringFromName("social.error.tryAgain.accesskey");
|
||||
}
|
||||
|
||||
function tryAgainButton() {
|
||||
config.tryAgainCallback();
|
||||
}
|
||||
|
||||
function loadQueryURL() {
|
||||
window.location.href = config.queryURL;
|
||||
}
|
||||
|
||||
function reloadProvider() {
|
||||
let provider = Social._getProviderFromOrigin(config.origin);
|
||||
provider.reload();
|
||||
}
|
||||
|
||||
parseQueryString();
|
||||
setUpStrings();
|
||||
]]></script>
|
||||
</html>
|
|
@ -85,10 +85,6 @@
|
|||
label="&bookmarkThisLinkCmd.label;"
|
||||
accesskey="&bookmarkThisLinkCmd.accesskey;"
|
||||
oncommand="gContextMenu.bookmarkLink();"/>
|
||||
<menuitem id="context-sharelink"
|
||||
label="&shareLink.label;"
|
||||
accesskey="&shareLink.accesskey;"
|
||||
oncommand="gContextMenu.shareLink();"/>
|
||||
<menuitem id="context-savelink"
|
||||
label="&saveLinkCmd.label;"
|
||||
accesskey="&saveLinkCmd.accesskey;"
|
||||
|
@ -212,10 +208,6 @@
|
|||
label="&saveImageCmd.label;"
|
||||
accesskey="&saveImageCmd.accesskey;"
|
||||
oncommand="gContextMenu.saveMedia();"/>
|
||||
<menuitem id="context-shareimage"
|
||||
label="&shareImage.label;"
|
||||
accesskey="&shareImage.accesskey;"
|
||||
oncommand="gContextMenu.shareImage();"/>
|
||||
<menuitem id="context-sendimage"
|
||||
label="&emailImageCmd.label;"
|
||||
accesskey="&emailImageCmd.accesskey;"
|
||||
|
@ -237,10 +229,6 @@
|
|||
label="&saveVideoCmd.label;"
|
||||
accesskey="&saveVideoCmd.accesskey;"
|
||||
oncommand="gContextMenu.saveMedia();"/>
|
||||
<menuitem id="context-sharevideo"
|
||||
label="&shareVideo.label;"
|
||||
accesskey="&shareVideo.accesskey;"
|
||||
oncommand="gContextMenu.shareVideo();"/>
|
||||
<menuitem id="context-saveaudio"
|
||||
label="&saveAudioCmd.label;"
|
||||
accesskey="&saveAudioCmd.accesskey;"
|
||||
|
@ -271,10 +259,6 @@
|
|||
accesskey="&hidePluginCmd.accesskey;"
|
||||
oncommand="gContextMenu.hidePlugin();"/>
|
||||
<menuseparator id="context-sep-ctp"/>
|
||||
<menuitem id="context-sharepage"
|
||||
label="&sharePageCmd.label;"
|
||||
accesskey="&sharePageCmd.accesskey;"
|
||||
oncommand="SocialShare.sharePage();"/>
|
||||
<menuitem id="context-savepage"
|
||||
label="&savePageCmd.label;"
|
||||
accesskey="&savePageCmd.accesskey2;"
|
||||
|
@ -334,10 +318,6 @@
|
|||
<menupopup id="context-sendlinktodevice-popup"
|
||||
onpopupshowing="gSync.populateSendTabToDevicesMenu(event.target, gContextMenu.linkURL, gContextMenu.linkTextStr);"/>
|
||||
</menu>
|
||||
<menuitem id="context-shareselect"
|
||||
label="&shareSelect.label;"
|
||||
accesskey="&shareSelect.accesskey;"
|
||||
oncommand="gContextMenu.shareSelect();"/>
|
||||
<menuseparator id="frame-sep"/>
|
||||
<menu id="frame" label="&thisFrameMenu.label;" accesskey="&thisFrameMenu.accesskey;">
|
||||
<menupopup>
|
||||
|
|
|
@ -108,8 +108,6 @@
|
|||
#endif
|
||||
<command id="History:UndoCloseTab" oncommand="undoCloseTab();"/>
|
||||
<command id="History:UndoCloseWindow" oncommand="undoCloseWindow();"/>
|
||||
<command id="Social:SharePage" oncommand="SocialShare.sharePage();"/>
|
||||
<command id="Social:Addons" oncommand="BrowserOpenAddonsMgr('addons://list/service');"/>
|
||||
</commandset>
|
||||
|
||||
<commandset id="placesCommands">
|
||||
|
@ -120,7 +118,6 @@
|
|||
</commandset>
|
||||
|
||||
<broadcasterset id="mainBroadcasterSet">
|
||||
<broadcaster id="Social:PageShareable" disabled="true"/>
|
||||
<broadcaster id="viewBookmarksSidebar" autoCheck="false" label="&bookmarksButton.label;"
|
||||
type="checkbox" group="sidebar" sidebarurl="chrome://browser/content/bookmarks/bookmarksPanel.xul"
|
||||
oncommand="SidebarUI.toggle('viewBookmarksSidebar');"/>
|
||||
|
|
|
@ -1,513 +0,0 @@
|
|||
/* 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/. */
|
||||
|
||||
/* eslint-env mozilla/browser-window */
|
||||
/* global OpenGraphBuilder:false, DynamicResizeWatcher:false, Utils:false*/
|
||||
|
||||
// the "exported" symbols
|
||||
var SocialUI,
|
||||
SocialShare,
|
||||
SocialActivationListener;
|
||||
|
||||
(function() {
|
||||
"use strict";
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "OpenGraphBuilder", function() {
|
||||
let tmp = {};
|
||||
Cu.import("resource:///modules/Social.jsm", tmp);
|
||||
return tmp.OpenGraphBuilder;
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "DynamicResizeWatcher", function() {
|
||||
let tmp = {};
|
||||
Cu.import("resource:///modules/Social.jsm", tmp);
|
||||
return tmp.DynamicResizeWatcher;
|
||||
});
|
||||
|
||||
let messageManager = window.messageManager;
|
||||
let openUILinkIn = window.openUILinkIn;
|
||||
|
||||
SocialUI = {
|
||||
_initialized: false,
|
||||
|
||||
// Called on delayed startup to initialize the UI
|
||||
init: function SocialUI_init() {
|
||||
if (this._initialized) {
|
||||
return;
|
||||
}
|
||||
let mm = window.getGroupMessageManager("social");
|
||||
mm.loadFrameScript("chrome://browser/content/content.js", true);
|
||||
mm.loadFrameScript("chrome://browser/content/social-content.js", true);
|
||||
|
||||
Services.obs.addObserver(this, "social:providers-changed");
|
||||
|
||||
CustomizableUI.addListener(this);
|
||||
SocialActivationListener.init();
|
||||
|
||||
Social.init().then((update) => {
|
||||
if (update)
|
||||
this._providersChanged();
|
||||
});
|
||||
|
||||
this._initialized = true;
|
||||
},
|
||||
|
||||
// Called on window unload
|
||||
uninit: function SocialUI_uninit() {
|
||||
if (!this._initialized) {
|
||||
return;
|
||||
}
|
||||
Services.obs.removeObserver(this, "social:providers-changed");
|
||||
|
||||
CustomizableUI.removeListener(this);
|
||||
SocialActivationListener.uninit();
|
||||
|
||||
this._initialized = false;
|
||||
},
|
||||
|
||||
observe: function SocialUI_observe(subject, topic, data) {
|
||||
switch (topic) {
|
||||
case "social:providers-changed":
|
||||
this._providersChanged();
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
_providersChanged() {
|
||||
SocialShare.populateProviderMenu();
|
||||
},
|
||||
|
||||
showLearnMore() {
|
||||
let url = Services.urlFormatter.formatURLPref("app.support.baseURL") + "social-api";
|
||||
openUILinkIn(url, "tab");
|
||||
},
|
||||
|
||||
closeSocialPanelForLinkTraversal(target, linkNode) {
|
||||
// No need to close the panel if this traversal was not retargeted
|
||||
if (target == "" || target == "_self")
|
||||
return;
|
||||
|
||||
// Check to see whether this link traversal was in a social panel
|
||||
let win = linkNode.ownerGlobal;
|
||||
let container = win.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.QueryInterface(Ci.nsIDocShell)
|
||||
.chromeEventHandler;
|
||||
let containerParent = container.parentNode;
|
||||
if (containerParent.classList.contains("social-panel") &&
|
||||
containerParent instanceof Ci.nsIDOMXULPopupElement) {
|
||||
// allow the link traversal to finish before closing the panel
|
||||
setTimeout(() => {
|
||||
containerParent.hidePopup();
|
||||
}, 0);
|
||||
}
|
||||
},
|
||||
|
||||
get _chromeless() {
|
||||
// Is this a popup window that doesn't want chrome shown?
|
||||
let docElem = document.documentElement;
|
||||
// extrachrome is not restored during session restore, so we need
|
||||
// to check for the toolbar as well.
|
||||
let chromeless = docElem.getAttribute("chromehidden").includes("extrachrome") ||
|
||||
docElem.getAttribute("chromehidden").includes("toolbar");
|
||||
// This property is "fixed" for a window, so avoid doing the check above
|
||||
// multiple times...
|
||||
delete this._chromeless;
|
||||
this._chromeless = chromeless;
|
||||
return chromeless;
|
||||
},
|
||||
|
||||
get enabled() {
|
||||
// Returns whether social is enabled *for this window*.
|
||||
if (this._chromeless)
|
||||
return false;
|
||||
return Social.providers.length > 0;
|
||||
},
|
||||
|
||||
canSharePage(aURI) {
|
||||
return (aURI && (aURI.schemeIs("http") || aURI.schemeIs("https")));
|
||||
},
|
||||
|
||||
onCustomizeEnd(aWindow) {
|
||||
if (aWindow != window)
|
||||
return;
|
||||
// customization mode gets buttons out of sync with command updating, fix
|
||||
// the disabled state
|
||||
let canShare = this.canSharePage(gBrowser.currentURI);
|
||||
let shareButton = SocialShare.shareButton;
|
||||
if (shareButton) {
|
||||
if (canShare) {
|
||||
shareButton.removeAttribute("disabled")
|
||||
} else {
|
||||
shareButton.setAttribute("disabled", "true")
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// called on tab/urlbar/location changes and after customization. Update
|
||||
// anything that is tab specific.
|
||||
updateState() {
|
||||
goSetCommandEnabled("Social:PageShareable", this.canSharePage(gBrowser.currentURI));
|
||||
}
|
||||
}
|
||||
|
||||
// message manager handlers
|
||||
SocialActivationListener = {
|
||||
init() {
|
||||
messageManager.addMessageListener("Social:Activation", this);
|
||||
},
|
||||
uninit() {
|
||||
messageManager.removeMessageListener("Social:Activation", this);
|
||||
},
|
||||
receiveMessage(aMessage) {
|
||||
let data = aMessage.json;
|
||||
let browser = aMessage.target;
|
||||
data.window = window;
|
||||
// if the source if the message is the share panel, we do a one-click
|
||||
// installation. The source of activations is controlled by the
|
||||
// social.directories preference
|
||||
let options;
|
||||
if (browser == SocialShare.iframe && Services.prefs.getBoolPref("social.share.activationPanelEnabled")) {
|
||||
options = { bypassContentCheck: true, bypassInstallPanel: true };
|
||||
}
|
||||
|
||||
Social.installProvider(data, function(manifest) {
|
||||
Social.activateFromOrigin(manifest.origin, function(provider) {
|
||||
if (provider.shareURL) {
|
||||
// Ensure that the share button is somewhere usable.
|
||||
// SocialShare.shareButton may return null if it is in the menu-panel
|
||||
// and has never been visible, so we check the widget directly. If
|
||||
// there is no area for the widget we move it into the toolbar.
|
||||
let widget = CustomizableUI.getWidget("social-share-button");
|
||||
// If the panel is already open, we can be sure that the provider can
|
||||
// already be accessed, possibly anchored to another toolbar button.
|
||||
// In that case we don't move the widget.
|
||||
if (!widget.areaType && SocialShare.panel.state != "open") {
|
||||
CustomizableUI.addWidgetToArea("social-share-button", CustomizableUI.AREA_NAVBAR);
|
||||
// Ensure correct state.
|
||||
SocialUI.onCustomizeEnd(window);
|
||||
}
|
||||
|
||||
// make this new provider the selected provider. If the panel hasn't
|
||||
// been opened, we need to make the frame first.
|
||||
SocialShare._createFrame();
|
||||
SocialShare.iframe.setAttribute("src", "data:text/plain;charset=utf8,");
|
||||
SocialShare.iframe.setAttribute("origin", provider.origin);
|
||||
// get the right button selected
|
||||
SocialShare.populateProviderMenu();
|
||||
if (SocialShare.panel.state == "open") {
|
||||
SocialShare.sharePage(provider.origin);
|
||||
}
|
||||
}
|
||||
if (provider.postActivationURL) {
|
||||
// if activated from an open share panel, we load the landing page in
|
||||
// a background tab
|
||||
let triggeringPrincipal = Utils.deserializePrincipal(aMessage.data.triggeringPrincipal);
|
||||
gBrowser.loadOneTab(provider.postActivationURL, {
|
||||
inBackground: SocialShare.panel.state == "open",
|
||||
triggeringPrincipal,
|
||||
});
|
||||
}
|
||||
});
|
||||
}, options);
|
||||
}
|
||||
}
|
||||
|
||||
SocialShare = {
|
||||
get _dynamicResizer() {
|
||||
delete this._dynamicResizer;
|
||||
this._dynamicResizer = new DynamicResizeWatcher();
|
||||
return this._dynamicResizer;
|
||||
},
|
||||
|
||||
// Share panel may be attached to the overflow or menu button depending on
|
||||
// customization, we need to manage open state of the anchor.
|
||||
get anchor() {
|
||||
let widget = CustomizableUI.getWidget("social-share-button");
|
||||
return widget.forWindow(window).anchor;
|
||||
},
|
||||
// Holds the anchor node in use whilst the panel is open, because it may vary.
|
||||
_currentAnchor: null,
|
||||
|
||||
get panel() {
|
||||
return document.getElementById("social-share-panel");
|
||||
},
|
||||
|
||||
get iframe() {
|
||||
// panel.firstChild is our toolbar hbox, panel.lastChild is the iframe
|
||||
// container hbox used for an interstitial "loading" graphic
|
||||
return this.panel.lastChild.firstChild;
|
||||
},
|
||||
|
||||
uninit() {
|
||||
if (this.iframe) {
|
||||
let mm = this.messageManager;
|
||||
mm.removeMessageListener("PageVisibility:Show", this);
|
||||
mm.removeMessageListener("PageVisibility:Hide", this);
|
||||
mm.removeMessageListener("Social:DOMWindowClose", this);
|
||||
this.iframe.removeEventListener("load", this);
|
||||
this.iframe.remove();
|
||||
}
|
||||
},
|
||||
|
||||
_createFrame() {
|
||||
let panel = this.panel;
|
||||
if (this.iframe)
|
||||
return;
|
||||
this.panel.hidden = false;
|
||||
// create and initialize the panel for this window
|
||||
let iframe = document.createElement("browser");
|
||||
iframe.setAttribute("type", "content");
|
||||
iframe.setAttribute("class", "social-share-frame");
|
||||
iframe.setAttribute("context", "contentAreaContextMenu");
|
||||
iframe.setAttribute("tooltip", "aHTMLTooltip");
|
||||
iframe.setAttribute("disableglobalhistory", "true");
|
||||
iframe.setAttribute("flex", "1");
|
||||
iframe.setAttribute("message", "true");
|
||||
iframe.setAttribute("messagemanagergroup", "social");
|
||||
panel.lastChild.appendChild(iframe);
|
||||
let mm = this.messageManager;
|
||||
mm.addMessageListener("PageVisibility:Show", this);
|
||||
mm.addMessageListener("PageVisibility:Hide", this);
|
||||
mm.sendAsyncMessage("Social:SetErrorURL",
|
||||
{ template: "about:socialerror?mode=compactInfo&origin=%{origin}&url=%{url}" });
|
||||
iframe.addEventListener("load", this, true);
|
||||
mm.addMessageListener("Social:DOMWindowClose", this);
|
||||
|
||||
this.populateProviderMenu();
|
||||
},
|
||||
|
||||
get messageManager() {
|
||||
// The xbl bindings for the iframe may not exist yet, so we can't
|
||||
// access iframe.messageManager directly - but can get at it with this dance.
|
||||
return this.iframe.QueryInterface(Components.interfaces.nsIFrameLoaderOwner).frameLoader.messageManager;
|
||||
},
|
||||
|
||||
receiveMessage(aMessage) {
|
||||
let iframe = this.iframe;
|
||||
switch (aMessage.name) {
|
||||
case "PageVisibility:Show":
|
||||
SocialShare._dynamicResizer.start(iframe.parentNode, iframe);
|
||||
break;
|
||||
case "PageVisibility:Hide":
|
||||
SocialShare._dynamicResizer.stop();
|
||||
break;
|
||||
case "Social:DOMWindowClose":
|
||||
this.panel.hidePopup();
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
handleEvent(event) {
|
||||
switch (event.type) {
|
||||
case "load": {
|
||||
this.iframe.parentNode.removeAttribute("loading");
|
||||
if (this.currentShare)
|
||||
SocialShare.messageManager.sendAsyncMessage("Social:OpenGraphData", this.currentShare);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
getSelectedProvider() {
|
||||
let provider;
|
||||
let lastProviderOrigin = this.iframe && this.iframe.getAttribute("origin");
|
||||
if (lastProviderOrigin) {
|
||||
provider = Social._getProviderFromOrigin(lastProviderOrigin);
|
||||
}
|
||||
return provider;
|
||||
},
|
||||
|
||||
createTooltip(event) {
|
||||
let tt = event.target;
|
||||
let provider = Social._getProviderFromOrigin(tt.triggerNode.getAttribute("origin"));
|
||||
tt.firstChild.setAttribute("value", provider.name);
|
||||
tt.lastChild.setAttribute("value", provider.origin);
|
||||
},
|
||||
|
||||
populateProviderMenu() {
|
||||
if (!this.iframe)
|
||||
return;
|
||||
let providers = Social.providers.filter(p => p.shareURL);
|
||||
let hbox = document.getElementById("social-share-provider-buttons");
|
||||
// remove everything before the add-share-provider button (which should also
|
||||
// be lastChild if any share providers were added)
|
||||
let addButton = document.getElementById("add-share-provider");
|
||||
while (hbox.lastChild != addButton) {
|
||||
hbox.removeChild(hbox.lastChild);
|
||||
}
|
||||
let selectedProvider = this.getSelectedProvider();
|
||||
for (let provider of providers) {
|
||||
let button = document.createElement("toolbarbutton");
|
||||
button.setAttribute("class", "toolbarbutton-1 share-provider-button");
|
||||
button.setAttribute("type", "radio");
|
||||
button.setAttribute("group", "share-providers");
|
||||
button.setAttribute("image", provider.iconURL);
|
||||
button.setAttribute("tooltip", "share-button-tooltip");
|
||||
button.setAttribute("origin", provider.origin);
|
||||
button.setAttribute("label", provider.name);
|
||||
button.setAttribute("oncommand", "SocialShare.sharePage(this.getAttribute('origin'));");
|
||||
if (provider == selectedProvider) {
|
||||
this.defaultButton = button;
|
||||
}
|
||||
hbox.appendChild(button);
|
||||
}
|
||||
if (!this.defaultButton) {
|
||||
this.defaultButton = addButton;
|
||||
}
|
||||
this.defaultButton.setAttribute("checked", "true");
|
||||
},
|
||||
|
||||
get shareButton() {
|
||||
// web-panels (bookmark/sidebar) don't include customizableui, so
|
||||
// nsContextMenu fails when accessing shareButton, breaking
|
||||
// browser_bug409481.js.
|
||||
if (document.documentElement.getAttribute("windowtype") !== "navigator:browser")
|
||||
return null;
|
||||
let widget = CustomizableUI.getWidget("social-share-button");
|
||||
if (!widget || !widget.areaType)
|
||||
return null;
|
||||
return widget.forWindow(window).node;
|
||||
},
|
||||
|
||||
_onclick() {
|
||||
Services.telemetry.getHistogramById("SOCIAL_PANEL_CLICKS").add(0);
|
||||
},
|
||||
|
||||
onShowing() {
|
||||
(this._currentAnchor || this.anchor).setAttribute("open", "true");
|
||||
this.iframe.addEventListener("click", this._onclick, true);
|
||||
},
|
||||
|
||||
onHidden() {
|
||||
(this._currentAnchor || this.anchor).removeAttribute("open");
|
||||
this._currentAnchor = null;
|
||||
this.iframe.docShellIsActive = false;
|
||||
this.iframe.removeEventListener("click", this._onclick, true);
|
||||
this.iframe.setAttribute("src", "data:text/plain;charset=utf8,");
|
||||
// make sure that the frame is unloaded after it is hidden
|
||||
this.messageManager.sendAsyncMessage("Social:ClearFrame");
|
||||
this.currentShare = null;
|
||||
// share panel use is over, purge any history
|
||||
this.iframe.purgeSessionHistory();
|
||||
},
|
||||
|
||||
sharePage(providerOrigin, graphData, target, anchor) {
|
||||
// if providerOrigin is undefined, we use the last-used provider, or the
|
||||
// current/default provider. The provider selection in the share panel
|
||||
// will call sharePage with an origin for us to switch to.
|
||||
this._createFrame();
|
||||
let iframe = this.iframe;
|
||||
|
||||
// graphData is an optional param that either defines the full set of data
|
||||
// to be shared, or partial data about the current page. It is set by a call
|
||||
// in mozSocial API, or via nsContentMenu calls. If it is present, it MUST
|
||||
// define at least url. If it is undefined, we're sharing the current url in
|
||||
// the browser tab.
|
||||
let sharedPageData = graphData || this.currentShare;
|
||||
let sharedURI = sharedPageData ? Services.io.newURI(sharedPageData.url) :
|
||||
gBrowser.currentURI;
|
||||
if (!SocialUI.canSharePage(sharedURI))
|
||||
return;
|
||||
|
||||
let browserMM = gBrowser.selectedBrowser.messageManager;
|
||||
|
||||
// the point of this action type is that we can use existing share
|
||||
// endpoints (e.g. oexchange) that do not support additional
|
||||
// socialapi functionality. One tweak is that we shoot an event
|
||||
// containing the open graph data.
|
||||
let _dataFn;
|
||||
if (!sharedPageData || sharedURI == gBrowser.currentURI) {
|
||||
browserMM.addMessageListener("PageMetadata:PageDataResult", _dataFn = (msg) => {
|
||||
browserMM.removeMessageListener("PageMetadata:PageDataResult", _dataFn);
|
||||
let pageData = msg.json;
|
||||
if (graphData) {
|
||||
// overwrite data retreived from page with data given to us as a param
|
||||
for (let p in graphData) {
|
||||
pageData[p] = graphData[p];
|
||||
}
|
||||
}
|
||||
this.sharePage(providerOrigin, pageData, target, anchor);
|
||||
});
|
||||
browserMM.sendAsyncMessage("PageMetadata:GetPageData", null, { target });
|
||||
return;
|
||||
}
|
||||
// if this is a share of a selected item, get any microformats
|
||||
if (!sharedPageData.microformats && target) {
|
||||
browserMM.addMessageListener("PageMetadata:MicroformatsResult", _dataFn = (msg) => {
|
||||
browserMM.removeMessageListener("PageMetadata:MicroformatsResult", _dataFn);
|
||||
sharedPageData.microformats = msg.data;
|
||||
this.sharePage(providerOrigin, sharedPageData, target, anchor);
|
||||
});
|
||||
browserMM.sendAsyncMessage("PageMetadata:GetMicroformats", null, { target });
|
||||
return;
|
||||
}
|
||||
this.currentShare = sharedPageData;
|
||||
|
||||
let provider;
|
||||
if (providerOrigin)
|
||||
provider = Social._getProviderFromOrigin(providerOrigin);
|
||||
else
|
||||
provider = this.getSelectedProvider();
|
||||
if (!provider || !provider.shareURL) {
|
||||
this.showDirectory(anchor);
|
||||
return;
|
||||
}
|
||||
// check the menu button
|
||||
let hbox = document.getElementById("social-share-provider-buttons");
|
||||
let btn = hbox.querySelector("[origin='" + provider.origin + "']");
|
||||
if (btn)
|
||||
btn.checked = true;
|
||||
|
||||
let shareEndpoint = OpenGraphBuilder.generateEndpointURL(provider.shareURL, sharedPageData);
|
||||
|
||||
this._dynamicResizer.stop();
|
||||
let size = provider.getPageSize("share");
|
||||
if (size) {
|
||||
// let the css on the share panel define width, but height
|
||||
// calculations dont work on all sites, so we allow that to be
|
||||
// defined.
|
||||
delete size.width;
|
||||
}
|
||||
|
||||
// if we've already loaded this provider/page share endpoint, we don't want
|
||||
// to add another load event listener.
|
||||
let endpointMatch = shareEndpoint == iframe.getAttribute("src");
|
||||
if (endpointMatch) {
|
||||
this._dynamicResizer.start(iframe.parentNode, iframe, size);
|
||||
iframe.docShellIsActive = true;
|
||||
SocialShare.messageManager.sendAsyncMessage("Social:OpenGraphData", this.currentShare);
|
||||
} else {
|
||||
iframe.parentNode.setAttribute("loading", "true");
|
||||
}
|
||||
// if the user switched between share providers we do not want that history
|
||||
// available.
|
||||
iframe.purgeSessionHistory();
|
||||
|
||||
// always ensure that origin belongs to the endpoint
|
||||
iframe.setAttribute("origin", provider.origin);
|
||||
iframe.setAttribute("src", shareEndpoint);
|
||||
this._openPanel(anchor);
|
||||
},
|
||||
|
||||
showDirectory(anchor) {
|
||||
this._createFrame();
|
||||
let iframe = this.iframe;
|
||||
if (iframe.getAttribute("src") == "about:providerdirectory")
|
||||
return;
|
||||
iframe.removeAttribute("origin");
|
||||
iframe.parentNode.setAttribute("loading", "true");
|
||||
|
||||
iframe.setAttribute("src", "about:providerdirectory");
|
||||
this._openPanel(anchor);
|
||||
},
|
||||
|
||||
_openPanel(anchor) {
|
||||
this._currentAnchor = anchor || this.anchor;
|
||||
anchor = document.getAnonymousElementByAttribute(this._currentAnchor, "class", "toolbarbutton-icon");
|
||||
this.panel.openPopup(anchor, "bottomcenter topright", 0, 0, false, false);
|
||||
Services.telemetry.getHistogramById("SOCIAL_TOOLBAR_BUTTONS").add(0);
|
||||
}
|
||||
};
|
||||
|
||||
}).call(this);
|
|
@ -160,7 +160,9 @@ var TabsInTitlebar = {
|
|||
// then later set the properties affecting layout together in a batch.
|
||||
|
||||
// Get the height of the tabs toolbar:
|
||||
let tabsHeight = rect($("TabsToolbar")).height;
|
||||
let tabsToolbar = $("TabsToolbar");
|
||||
let tabsStyles = window.getComputedStyle(tabsToolbar);
|
||||
let fullTabsHeight = rect($("TabsToolbar")).height + verticalMargins(tabsStyles);
|
||||
// Buttons first:
|
||||
let captionButtonsBoxWidth = rect($("titlebar-buttonbox-container")).width;
|
||||
|
||||
|
@ -186,7 +188,8 @@ var TabsInTitlebar = {
|
|||
// tab strip height if we're not showing a menu bar.
|
||||
if (AppConstants.isPlatformAndVersionAtLeast("win", "10.0")) {
|
||||
if (!menuHeight) {
|
||||
titlebarContentHeight = tabsHeight;
|
||||
// Add a pixel to slightly overlap the navbar border.
|
||||
titlebarContentHeight = fullTabsHeight + 1;
|
||||
$("titlebar-buttonbox").style.height = titlebarContentHeight + "px";
|
||||
}
|
||||
}
|
||||
|
@ -220,7 +223,7 @@ var TabsInTitlebar = {
|
|||
|
||||
// Next, we calculate how much we need to stretch the titlebar down to
|
||||
// go all the way to the bottom of the tab strip, if necessary.
|
||||
let tabAndMenuHeight = tabsHeight + fullMenuHeight;
|
||||
let tabAndMenuHeight = fullTabsHeight + fullMenuHeight;
|
||||
|
||||
if (tabAndMenuHeight > titlebarContentHeight) {
|
||||
// We need to increase the titlebar content's outer height (ie including margins)
|
||||
|
|
|
@ -1046,11 +1046,6 @@ html|*#gcli-output-frame,
|
|||
transition: none;
|
||||
}
|
||||
|
||||
panelview > .social-panel-frame {
|
||||
width: auto;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
/* Translation */
|
||||
notification[value="translation"] {
|
||||
-moz-binding: url("chrome://browser/content/translation-infobar.xml#translationbar");
|
||||
|
|
|
@ -55,7 +55,6 @@ XPCOMUtils.defineLazyModuleGetters(this, {
|
|||
ShortcutUtils: "resource://gre/modules/ShortcutUtils.jsm",
|
||||
SimpleServiceDiscovery: "resource://gre/modules/SimpleServiceDiscovery.jsm",
|
||||
SitePermissions: "resource:///modules/SitePermissions.jsm",
|
||||
Social: "resource:///modules/Social.jsm",
|
||||
TabCrashHandler: "resource:///modules/ContentCrashHandlers.jsm",
|
||||
TelemetryStopwatch: "resource://gre/modules/TelemetryStopwatch.jsm",
|
||||
Translation: "resource:///modules/translation/Translation.jsm",
|
||||
|
@ -100,10 +99,6 @@ XPCOMUtils.defineLazyScriptGetter(this, ["gGestureSupport", "gHistorySwipeAnimat
|
|||
"chrome://browser/content/browser-gestureSupport.js");
|
||||
XPCOMUtils.defineLazyScriptGetter(this, "gSafeBrowsing",
|
||||
"chrome://browser/content/browser-safebrowsing.js");
|
||||
XPCOMUtils.defineLazyScriptGetter(this, ["SocialUI",
|
||||
"SocialShare",
|
||||
"SocialActivationListener"],
|
||||
"chrome://browser/content/browser-social.js");
|
||||
XPCOMUtils.defineLazyScriptGetter(this, "gSync",
|
||||
"chrome://browser/content/browser-sync.js");
|
||||
XPCOMUtils.defineLazyScriptGetter(this, "gBrowserThumbnails",
|
||||
|
@ -1653,7 +1648,6 @@ var gBrowserInit = {
|
|||
RestoreLastSessionObserver.init();
|
||||
|
||||
SidebarUI.startDelayedLoad();
|
||||
SocialUI.init();
|
||||
|
||||
PanicButtonNotifier.init();
|
||||
});
|
||||
|
@ -1830,7 +1824,6 @@ var gBrowserInit = {
|
|||
|
||||
gPrefService.removeObserver(ctrlTab.prefName, ctrlTab);
|
||||
ctrlTab.uninit();
|
||||
SocialUI.uninit();
|
||||
gBrowserThumbnails.uninit();
|
||||
FullZoom.destroy();
|
||||
|
||||
|
@ -4502,9 +4495,7 @@ var XULBrowserWindow = {
|
|||
|
||||
// Called before links are navigated to to allow us to retarget them if needed.
|
||||
onBeforeLinkTraversal(originalTarget, linkURI, linkNode, isAppTab) {
|
||||
let target = BrowserUtils.onBeforeLinkTraversal(originalTarget, linkURI, linkNode, isAppTab);
|
||||
SocialUI.closeSocialPanelForLinkTraversal(target, linkNode);
|
||||
return target;
|
||||
return BrowserUtils.onBeforeLinkTraversal(originalTarget, linkURI, linkNode, isAppTab);
|
||||
},
|
||||
|
||||
// Check whether this URI should load in the current process
|
||||
|
@ -4686,8 +4677,6 @@ var XULBrowserWindow = {
|
|||
|
||||
gIdentityHandler.onLocationChange();
|
||||
|
||||
SocialUI.updateState();
|
||||
|
||||
gTabletModePageCounter.inc();
|
||||
|
||||
// Utility functions for disabling find
|
||||
|
@ -4990,8 +4979,9 @@ var CombinedStopReload = {
|
|||
|
||||
onTabSwitch() {
|
||||
// Reset the time in the event of a tabswitch since the stored time
|
||||
// would have been associated with the previous tab.
|
||||
this.timeWhenSwitchedToStop = 0;
|
||||
// would have been associated with the previous tab, so the animation will
|
||||
// still run if the page has been loading until long after the tab switch.
|
||||
this.timeWhenSwitchedToStop = window.performance.now();
|
||||
},
|
||||
|
||||
switchToStop(aRequest, aWebProgress) {
|
||||
|
@ -5002,11 +4992,11 @@ var CombinedStopReload = {
|
|||
// Store the time that we switched to the stop button only if a request
|
||||
// is active. Requests are null if the switch is related to a tabswitch.
|
||||
// This is used to determine if we should show the stop->reload animation.
|
||||
if (aRequest) {
|
||||
if (aRequest instanceof Ci.nsIRequest) {
|
||||
this.timeWhenSwitchedToStop = window.performance.now();
|
||||
}
|
||||
|
||||
let shouldAnimate = aRequest &&
|
||||
let shouldAnimate = aRequest instanceof Ci.nsIRequest &&
|
||||
aWebProgress.isTopLevel &&
|
||||
aWebProgress.isLoadingDocument &&
|
||||
!gBrowser.tabAnimationsInProgress &&
|
||||
|
@ -5029,7 +5019,7 @@ var CombinedStopReload = {
|
|||
return;
|
||||
}
|
||||
|
||||
let shouldAnimate = aRequest &&
|
||||
let shouldAnimate = aRequest instanceof Ci.nsIRequest &&
|
||||
aWebProgress.isTopLevel &&
|
||||
!aWebProgress.isLoadingDocument &&
|
||||
!gBrowser.tabAnimationsInProgress &&
|
||||
|
@ -5070,10 +5060,10 @@ var CombinedStopReload = {
|
|||
_loadTimeExceedsMinimumForAnimation() {
|
||||
// If the time between switching to the stop button then switching to
|
||||
// the reload button exceeds 150ms, then we will show the animation.
|
||||
// If we don't know when we switched to stop (a tabswitch occured while
|
||||
// the page was loading), then we will not prevent the animation from
|
||||
// occuring.
|
||||
return !this.timeWhenSwitchedToStop ||
|
||||
// If we don't know when we switched to stop (switchToStop is called
|
||||
// after init but before switchToReload), then we will prevent the
|
||||
// animation from occuring.
|
||||
return this.timeWhenSwitchedToStop &&
|
||||
window.performance.now() - this.timeWhenSwitchedToStop > 150;
|
||||
},
|
||||
|
||||
|
|
|
@ -264,26 +264,6 @@
|
|||
<box id="UITourHighlight"></box>
|
||||
</panel>
|
||||
|
||||
<panel id="social-share-panel"
|
||||
class="social-panel"
|
||||
type="arrow"
|
||||
orient="vertical"
|
||||
onpopupshowing="SocialShare.onShowing()"
|
||||
onpopuphidden="SocialShare.onHidden()"
|
||||
hidden="true">
|
||||
<hbox class="social-share-toolbar">
|
||||
<toolbarbutton id="manage-share-providers" class="share-provider-button"
|
||||
tooltiptext="&social.addons.label;"
|
||||
oncommand="BrowserOpenAddonsMgr('addons://list/service');
|
||||
this.parentNode.parentNode.hidePopup();"/>
|
||||
<arrowscrollbox id="social-share-provider-buttons" orient="horizontal" flex="1" pack="end">
|
||||
<toolbarbutton id="add-share-provider" class="share-provider-button" type="radio"
|
||||
group="share-providers" tooltiptext="&findShareServices.label;"
|
||||
oncommand="SocialShare.showDirectory()"/>
|
||||
</arrowscrollbox>
|
||||
</hbox>
|
||||
<hbox id="share-container" flex="1"/>
|
||||
</panel>
|
||||
<panel id="sidebarMenu-popup"
|
||||
class="cui-widget-panel"
|
||||
role="group"
|
||||
|
@ -498,11 +478,6 @@
|
|||
#endif
|
||||
</tooltip>
|
||||
|
||||
<tooltip id="share-button-tooltip" onpopupshowing="SocialShare.createTooltip(event);">
|
||||
<label class="tooltip-label"/>
|
||||
<label class="tooltip-label"/>
|
||||
</tooltip>
|
||||
|
||||
#include popup-notifications.inc
|
||||
|
||||
#include ../../components/customizableui/content/panelUI.inc.xul
|
||||
|
|
|
@ -826,38 +826,6 @@ var PageMetadataMessenger = {
|
|||
}
|
||||
PageMetadataMessenger.init();
|
||||
|
||||
addEventListener("ActivateSocialFeature", function(aEvent) {
|
||||
let document = content.document;
|
||||
let dwu = content.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowUtils);
|
||||
if (!dwu.isHandlingUserInput) {
|
||||
Cu.reportError("attempt to activate provider without user input from " + document.nodePrincipal.origin);
|
||||
return;
|
||||
}
|
||||
|
||||
let node = aEvent.target;
|
||||
let ownerDocument = node.ownerDocument;
|
||||
let data = node.getAttribute("data-service");
|
||||
if (data) {
|
||||
try {
|
||||
data = JSON.parse(data);
|
||||
} catch (e) {
|
||||
Cu.reportError("Social Service manifest parse error: " + e);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
Cu.reportError("Social Service manifest not available");
|
||||
return;
|
||||
}
|
||||
|
||||
sendAsyncMessage("Social:Activation", {
|
||||
url: ownerDocument.location.href,
|
||||
origin: ownerDocument.nodePrincipal.origin,
|
||||
manifest: data,
|
||||
triggeringPrincipal: Utils.serializePrincipal(ownerDocument.nodePrincipal),
|
||||
});
|
||||
}, true, true);
|
||||
|
||||
addMessageListener("ContextMenu:SaveVideoFrameAsImage", (message) => {
|
||||
let video = message.objects.target;
|
||||
let canvas = content.document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
|
||||
|
|
|
@ -64,9 +64,6 @@ with Files("test/referrer/**"):
|
|||
with Files("test/siteIdentity/**"):
|
||||
BUG_COMPONENT = ("Firefox", "Site Identity and Permission Panels")
|
||||
|
||||
with Files("test/social/**"):
|
||||
BUG_COMPONENT = ("Firefox", "SocialAPI")
|
||||
|
||||
with Files("test/static/**"):
|
||||
BUG_COMPONENT = ("Firefox", "General")
|
||||
|
||||
|
@ -88,15 +85,9 @@ with Files("test/webextensions/**"):
|
|||
with Files("test/webrtc/**"):
|
||||
BUG_COMPONENT = ("Core", "WebRTC")
|
||||
|
||||
with Files("aboutProviderDirectory.xhtml"):
|
||||
BUG_COMPONENT = ("Firefox", "SocialAPI")
|
||||
|
||||
with Files("aboutNetError.xhtml"):
|
||||
BUG_COMPONENT = ("Firefox", "Security")
|
||||
|
||||
with Files("aboutSocialError.xhtml"):
|
||||
BUG_COMPONENT = ("Firefox", "SocialAPI")
|
||||
|
||||
with Files("blockedSite.xhtml"):
|
||||
BUG_COMPONENT = ("Toolkit", "Safe Browsing")
|
||||
|
||||
|
@ -133,9 +124,6 @@ with Files("browser-plugins.js"):
|
|||
with Files("browser-safebrowsing.js"):
|
||||
BUG_COMPONENT = ("Toolkit", "Safe Browsing")
|
||||
|
||||
with Files("*social*"):
|
||||
BUG_COMPONENT = ("Firefox", "SocialAPI")
|
||||
|
||||
with Files("browser-sync.js"):
|
||||
BUG_COMPONENT = ("Firefox", "Sync")
|
||||
|
||||
|
|
|
@ -374,13 +374,12 @@ nsContextMenu.prototype = {
|
|||
let bookmarkPage = document.getElementById("context-bookmarkpage");
|
||||
this.showItem(bookmarkPage,
|
||||
!(this.isContentSelected || this.onTextInput || this.onLink ||
|
||||
this.onImage || this.onVideo || this.onAudio || this.onSocial ||
|
||||
this.onImage || this.onVideo || this.onAudio ||
|
||||
this.onCanvas || this.inWebExtBrowser));
|
||||
bookmarkPage.setAttribute("tooltiptext", bookmarkPage.getAttribute("buttontooltiptext"));
|
||||
|
||||
this.showItem("context-bookmarklink", (this.onLink && !this.onMailtoLink &&
|
||||
!this.onSocial && !this.onMozExtLink) ||
|
||||
this.onPlainTextLink);
|
||||
!this.onMozExtLink) || this.onPlainTextLink);
|
||||
this.showItem("context-keywordfield",
|
||||
this.onTextInput && this.onKeywordField);
|
||||
this.showItem("frame", this.inFrame);
|
||||
|
@ -418,20 +417,6 @@ nsContextMenu.prototype = {
|
|||
this.onTextInput && !this.onNumeric && top.gBidiUI);
|
||||
this.showItem("context-bidi-page-direction-toggle",
|
||||
!this.onTextInput && top.gBidiUI);
|
||||
|
||||
// SocialShare
|
||||
let shareButton = SocialShare.shareButton;
|
||||
let shareEnabled = shareButton && !shareButton.disabled && !this.onSocial;
|
||||
let pageShare = shareEnabled && !(this.isContentSelected ||
|
||||
this.onTextInput || this.onLink || this.onImage ||
|
||||
this.onVideo || this.onAudio || this.onCanvas ||
|
||||
this.inWebExtBrowser);
|
||||
this.showItem("context-sharepage", pageShare);
|
||||
this.showItem("context-shareselect", shareEnabled && this.isContentSelected);
|
||||
this.showItem("context-sharelink", shareEnabled && (this.onLink || this.onPlainTextLink) && !this.onMailtoLink && !this.onMozExtLink);
|
||||
this.showItem("context-shareimage", shareEnabled && this.onImage);
|
||||
this.showItem("context-sharevideo", shareEnabled && this.onVideo);
|
||||
this.setItemAttr("context-sharevideo", "disabled", !this.mediaURL || this.mediaURL.startsWith("blob:") || this.mediaURL.startsWith("moz-extension:"));
|
||||
},
|
||||
|
||||
initSpellingItems() {
|
||||
|
@ -746,7 +731,6 @@ nsContextMenu.prototype = {
|
|||
this.principal = ownerDoc.nodePrincipal;
|
||||
this.frameOuterWindowID = WebNavigationFrames.getFrameId(ownerDoc.defaultView);
|
||||
}
|
||||
this.onSocial = !!this.browser.getAttribute("origin");
|
||||
this.webExtBrowserType = this.browser.getAttribute("webextension-view-type");
|
||||
this.inWebExtBrowser = !!this.webExtBrowserType;
|
||||
this.inTabBrowser = this.browser.ownerGlobal.gBrowser ?
|
||||
|
@ -1834,22 +1818,6 @@ nsContextMenu.prototype = {
|
|||
mm.sendAsyncMessage("ContextMenu:BookmarkFrame", null, { target: this.target });
|
||||
},
|
||||
|
||||
shareLink: function CM_shareLink() {
|
||||
SocialShare.sharePage(null, { url: this.linkURI.spec }, this.target);
|
||||
},
|
||||
|
||||
shareImage: function CM_shareImage() {
|
||||
SocialShare.sharePage(null, { url: this.imageURL, previews: [ this.mediaURL ] }, this.target);
|
||||
},
|
||||
|
||||
shareVideo: function CM_shareVideo() {
|
||||
SocialShare.sharePage(null, { url: this.mediaURL, source: this.mediaURL }, this.target);
|
||||
},
|
||||
|
||||
shareSelect: function CM_shareSelect() {
|
||||
SocialShare.sharePage(null, { url: this.browser.currentURI.spec, text: this.textSelected }, this.target);
|
||||
},
|
||||
|
||||
savePageAs: function CM_savePageAs() {
|
||||
saveBrowser(this.browser);
|
||||
},
|
||||
|
@ -1964,7 +1932,7 @@ nsContextMenu.prototype = {
|
|||
_getTelemetryPageContextInfo() {
|
||||
let rv = [];
|
||||
for (let k of ["isContentSelected", "onLink", "onImage", "onCanvas", "onVideo", "onAudio",
|
||||
"onTextInput", "onSocial", "inWebExtBrowser", "inTabBrowser"]) {
|
||||
"onTextInput", "inWebExtBrowser", "inTabBrowser"]) {
|
||||
if (this[k]) {
|
||||
rv.push(k.replace(/^(?:is|on)(.)/, (match, firstLetter) => firstLetter.toLowerCase()));
|
||||
}
|
||||
|
|
|
@ -1,170 +0,0 @@
|
|||
/* -*- 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/. */
|
||||
|
||||
/* This content script is intended for use by iframes in the share panel. */
|
||||
|
||||
/* eslint-env mozilla/frame-script */
|
||||
|
||||
var {interfaces: Ci, utils: Cu} = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
// social frames are always treated as app tabs
|
||||
docShell.isAppTab = true;
|
||||
|
||||
addEventListener("DOMContentLoaded", function(event) {
|
||||
if (event.target != content.document)
|
||||
return;
|
||||
// Some share panels (e.g. twitter and facebook) check content.opener, and if
|
||||
// it doesn't exist they act like they are in a browser tab. We want them to
|
||||
// act like they are in a dialog (which is the typical case).
|
||||
if (content && !content.opener) {
|
||||
content.opener = content;
|
||||
}
|
||||
hookWindowClose();
|
||||
disableDialogs();
|
||||
});
|
||||
|
||||
addMessageListener("Social:OpenGraphData", (message) => {
|
||||
let ev = new content.CustomEvent("OpenGraphData", { detail: JSON.stringify(message.data) });
|
||||
content.dispatchEvent(ev);
|
||||
});
|
||||
|
||||
addMessageListener("Social:ClearFrame", () => {
|
||||
docShell.createAboutBlankContentViewer(null);
|
||||
});
|
||||
|
||||
addEventListener("DOMWindowClose", (evt) => {
|
||||
// preventDefault stops the default window.close() function being called,
|
||||
// which doesn't actually close anything but causes things to get into
|
||||
// a bad state (an internal 'closed' flag is set and debug builds start
|
||||
// asserting as the window is used.).
|
||||
// None of the windows we inject this API into are suitable for this
|
||||
// default close behaviour, so even if we took no action above, we avoid
|
||||
// the default close from doing anything.
|
||||
evt.preventDefault();
|
||||
|
||||
// Tells the SocialShare class to close the panel
|
||||
sendAsyncMessage("Social:DOMWindowClose");
|
||||
});
|
||||
|
||||
function hookWindowClose() {
|
||||
// Allow scripts to close the "window". Because we are in a panel and not
|
||||
// in a full dialog, the DOMWindowClose listener above will only receive the
|
||||
// event if we do this.
|
||||
let dwu = content.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowUtils);
|
||||
dwu.allowScriptsToClose();
|
||||
}
|
||||
|
||||
function disableDialogs() {
|
||||
let windowUtils = content.QueryInterface(Ci.nsIInterfaceRequestor).
|
||||
getInterface(Ci.nsIDOMWindowUtils);
|
||||
windowUtils.disableDialogs();
|
||||
}
|
||||
|
||||
// Error handling class used to listen for network errors in the social frames
|
||||
// and replace them with a social-specific error page
|
||||
const SocialErrorListener = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMEventListener,
|
||||
Ci.nsIWebProgressListener,
|
||||
Ci.nsISupportsWeakReference,
|
||||
Ci.nsISupports]),
|
||||
|
||||
defaultTemplate: "about:socialerror?mode=tryAgainOnly&url=%{url}&origin=%{origin}",
|
||||
urlTemplate: null,
|
||||
|
||||
init() {
|
||||
addMessageListener("Social:SetErrorURL", this);
|
||||
let webProgress = docShell.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||
.getInterface(Components.interfaces.nsIWebProgress);
|
||||
webProgress.addProgressListener(this, Ci.nsIWebProgress.NOTIFY_STATE_REQUEST |
|
||||
Ci.nsIWebProgress.NOTIFY_LOCATION);
|
||||
},
|
||||
|
||||
receiveMessage(message) {
|
||||
switch (message.name) {
|
||||
case "Social:SetErrorURL":
|
||||
// Either a url or null to reset to default template.
|
||||
this.urlTemplate = message.data.template;
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
setErrorPage() {
|
||||
// if this is about:providerdirectory, use the directory iframe
|
||||
let frame = docShell.chromeEventHandler;
|
||||
let origin = frame.getAttribute("origin");
|
||||
let src = frame.getAttribute("src");
|
||||
if (src == "about:providerdirectory") {
|
||||
frame = content.document.getElementById("activation-frame");
|
||||
src = frame.getAttribute("src");
|
||||
}
|
||||
|
||||
let url = this.urlTemplate || this.defaultTemplate;
|
||||
url = url.replace("%{url}", encodeURIComponent(src));
|
||||
url = url.replace("%{origin}", encodeURIComponent(origin));
|
||||
if (frame != docShell.chromeEventHandler) {
|
||||
// Unable to access frame.docShell here. This is our own frame and doesn't
|
||||
// provide reload, so we'll just set the src.
|
||||
frame.setAttribute("src", url);
|
||||
} else {
|
||||
let webNav = docShell.QueryInterface(Ci.nsIWebNavigation);
|
||||
webNav.loadURI(url, null, null, null, null);
|
||||
}
|
||||
sendAsyncMessage("Social:ErrorPageNotify", {
|
||||
origin,
|
||||
url: src
|
||||
});
|
||||
},
|
||||
|
||||
onStateChange(aWebProgress, aRequest, aState, aStatus) {
|
||||
let failure = false;
|
||||
if ((aState & Ci.nsIWebProgressListener.STATE_IS_REQUEST))
|
||||
return;
|
||||
if ((aState & Ci.nsIWebProgressListener.STATE_STOP)) {
|
||||
if (aRequest instanceof Ci.nsIHttpChannel) {
|
||||
try {
|
||||
// Change the frame to an error page on 4xx (client errors)
|
||||
// and 5xx (server errors). responseStatus throws if it is not set.
|
||||
failure = aRequest.responseStatus >= 400 &&
|
||||
aRequest.responseStatus < 600;
|
||||
} catch (e) {
|
||||
failure = aStatus != Components.results.NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Calling cancel() will raise some OnStateChange notifications by itself,
|
||||
// so avoid doing that more than once
|
||||
if (failure && aStatus != Components.results.NS_BINDING_ABORTED) {
|
||||
// if tp is enabled and we get a failure, ignore failures (ie. STATE_STOP)
|
||||
// on child resources since they *may* have been blocked. We don't have an
|
||||
// easy way to know if a particular url is blocked by TP, only that
|
||||
// something was.
|
||||
if (docShell.hasTrackingContentBlocked) {
|
||||
let frame = docShell.chromeEventHandler;
|
||||
let src = frame.getAttribute("src");
|
||||
if (aRequest && aRequest.name != src) {
|
||||
Cu.reportError("SocialErrorListener ignoring blocked content error for " + aRequest.name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
aRequest.cancel(Components.results.NS_BINDING_ABORTED);
|
||||
this.setErrorPage();
|
||||
}
|
||||
},
|
||||
|
||||
onLocationChange(aWebProgress, aRequest, aLocation, aFlags) {
|
||||
if (aRequest && aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_ERROR_PAGE) {
|
||||
aRequest.cancel(Components.results.NS_BINDING_ABORTED);
|
||||
this.setErrorPage();
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
SocialErrorListener.init();
|
|
@ -3,6 +3,5 @@ support-files =
|
|||
!/browser/base/content/test/general/contextmenu_common.js
|
||||
subtst_contextmenu_webext.html
|
||||
|
||||
[browser_contextmenu_mozextension.js]
|
||||
[browser_contextmenu_touch.js]
|
||||
skip-if = !(os == 'win' && os_version == '10.0')
|
||||
|
|
|
@ -1,86 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
var { SocialService } = Cu.import("resource:///modules/SocialService.jsm", {});
|
||||
|
||||
let contextMenu;
|
||||
let hasPocket = Services.prefs.getBoolPref("extensions.pocket.enabled");
|
||||
let hasContainers = Services.prefs.getBoolPref("privacy.userContext.enabled");
|
||||
|
||||
// A social share provider
|
||||
let manifest = {
|
||||
name: "provider 1",
|
||||
origin: "https://example.com",
|
||||
iconURL: "https://example.com/browser/browser/base/content/test/general/moz.png",
|
||||
shareURL: "https://example.com/browser/browser/base/content/test/social/share.html"
|
||||
};
|
||||
|
||||
add_task(async function test_setup() {
|
||||
const example_base = "http://example.com/browser/browser/base/content/test/contextMenu/";
|
||||
const url = example_base + "subtst_contextmenu_webext.html";
|
||||
await BrowserTestUtils.openNewForegroundTab(gBrowser, url);
|
||||
|
||||
const chrome_base = "chrome://mochitests/content/browser/browser/base/content/test/general/";
|
||||
const contextmenu_common = chrome_base + "contextmenu_common.js";
|
||||
/* import-globals-from ../general/contextmenu_common.js */
|
||||
Services.scriptloader.loadSubScript(contextmenu_common, this);
|
||||
|
||||
// Enable social sharing functions in the browser, so the context menu item is shown.
|
||||
CustomizableUI.addWidgetToArea("social-share-button", CustomizableUI.AREA_NAVBAR);
|
||||
|
||||
await new Promise((resolve) => SocialService.addProvider(manifest, resolve));
|
||||
ok(SocialShare.shareButton && !SocialShare.shareButton.disabled, "Sharing is enabled");
|
||||
});
|
||||
|
||||
add_task(async function test_link() {
|
||||
// gets hidden for this case.
|
||||
await test_contextmenu("#link",
|
||||
["context-openlinkintab", true,
|
||||
...(hasContainers ? ["context-openlinkinusercontext-menu", true] : []),
|
||||
// We need a blank entry here because the containers submenu is
|
||||
// dynamically generated with no ids.
|
||||
...(hasContainers ? ["", null] : []),
|
||||
"context-openlink", true,
|
||||
"context-openlinkprivate", true,
|
||||
"---", null,
|
||||
"context-savelink", true,
|
||||
"context-copylink", true,
|
||||
"context-searchselect", true,
|
||||
"---", null,
|
||||
"context-sendlinktodevice", true, [], null,
|
||||
]
|
||||
);
|
||||
});
|
||||
|
||||
add_task(async function test_video() {
|
||||
await test_contextmenu("#video",
|
||||
["context-media-play", null,
|
||||
"context-media-mute", null,
|
||||
"context-media-playbackrate", null,
|
||||
["context-media-playbackrate-050x", null,
|
||||
"context-media-playbackrate-100x", null,
|
||||
"context-media-playbackrate-125x", null,
|
||||
"context-media-playbackrate-150x", null,
|
||||
"context-media-playbackrate-200x", null], null,
|
||||
"context-media-loop", null,
|
||||
"context-media-showcontrols", null,
|
||||
"context-video-fullscreen", null,
|
||||
"---", null,
|
||||
"context-viewvideo", null,
|
||||
"context-copyvideourl", null,
|
||||
"---", null,
|
||||
"context-savevideo", null,
|
||||
"context-sharevideo", false,
|
||||
"context-video-saveimage", null,
|
||||
"context-sendvideo", null,
|
||||
"context-castvideo", null,
|
||||
[], null
|
||||
]);
|
||||
});
|
||||
|
||||
add_task(async function test_cleanup() {
|
||||
lastElementSelector = null;
|
||||
await BrowserTestUtils.removeTab(gBrowser.selectedTab);
|
||||
await new Promise((resolve) => {
|
||||
return SocialService.disableProvider(manifest.origin, resolve);
|
||||
});
|
||||
});
|
|
@ -587,6 +587,7 @@ tags = psm
|
|||
support-files =
|
||||
file_window_activation.html
|
||||
file_window_activation2.html
|
||||
skip-if = stylo # bug 1390694
|
||||
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
|
||||
[browser_contextmenu_childprocess.js]
|
||||
# DO NOT ADD MORE TESTS HERE. USE A TOPICAL DIRECTORY INSTEAD.
|
||||
|
|
|
@ -1,11 +1,36 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
add_task(async function test() {
|
||||
add_task(async function test_blank() {
|
||||
await BrowserTestUtils.withNewTab({ gBrowser, url: "about:blank" },
|
||||
async function(browser) {
|
||||
BrowserTestUtils.loadURI(browser, "http://example.com");
|
||||
await BrowserTestUtils.browserLoaded(browser);
|
||||
ok(!gBrowser.canGoBack, "about:newtab wasn't added to the session history");
|
||||
ok(!gBrowser.canGoBack, "about:blank wasn't added to session history");
|
||||
});
|
||||
});
|
||||
|
||||
add_task(async function test_newtab() {
|
||||
await SpecialPowers.pushPrefEnv({set: [["browser.newtabpage.activity-stream.enabled", true]]});
|
||||
await BrowserTestUtils.withNewTab({ gBrowser, url: "about:blank" },
|
||||
async function(browser) {
|
||||
// Can't load it directly because that'll use a preloaded tab if present.
|
||||
BrowserTestUtils.loadURI(browser, "about:newtab");
|
||||
await BrowserTestUtils.browserLoaded(browser);
|
||||
|
||||
BrowserTestUtils.loadURI(browser, "http://example.com");
|
||||
await BrowserTestUtils.browserLoaded(browser);
|
||||
is(gBrowser.canGoBack, true, "about:newtab was added to the session history when AS was enabled.");
|
||||
});
|
||||
await SpecialPowers.pushPrefEnv({set: [["browser.newtabpage.activity-stream.enabled", false]]});
|
||||
await BrowserTestUtils.withNewTab({ gBrowser, url: "about:blank" },
|
||||
async function(browser) {
|
||||
// Can't load it directly because that'll use a preloaded tab if present.
|
||||
BrowserTestUtils.loadURI(browser, "about:newtab");
|
||||
await BrowserTestUtils.browserLoaded(browser);
|
||||
|
||||
BrowserTestUtils.loadURI(browser, "http://example.com");
|
||||
await BrowserTestUtils.browserLoaded(browser);
|
||||
is(gBrowser.canGoBack, false, "about:newtab was not added to the session history when AS was disabled.");
|
||||
});
|
||||
});
|
||||
|
|
|
@ -80,6 +80,16 @@ if (Services.appinfo.OS == "WINNT") {
|
|||
|
||||
if (Services.appinfo.OS == "WINNT" || Services.appinfo.OS == "Darwin") {
|
||||
EXPECTED_REFLOWS.push(
|
||||
{
|
||||
stack: [
|
||||
"verticalMargins@chrome://browser/content/browser-tabsintitlebar.js",
|
||||
"_update@chrome://browser/content/browser-tabsintitlebar.js",
|
||||
"init@chrome://browser/content/browser-tabsintitlebar.js",
|
||||
"handleEvent@chrome://browser/content/tabbrowser.xml",
|
||||
],
|
||||
times: 2, // This number should only ever go down - never up.
|
||||
},
|
||||
|
||||
{
|
||||
stack: [
|
||||
"rect@chrome://browser/content/browser-tabsintitlebar.js",
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
"extends": [
|
||||
"plugin:mozilla/browser-test"
|
||||
]
|
||||
};
|
|
@ -1,6 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist">
|
||||
<emItems>
|
||||
<emItem blockID="s1" id="test1.example.com@services.mozilla.org"></emItem>
|
||||
</emItems>
|
||||
</blocklist>
|
|
@ -1,24 +0,0 @@
|
|||
[DEFAULT]
|
||||
support-files =
|
||||
blocklist.xml
|
||||
head.js
|
||||
opengraph/og_invalid_url.html
|
||||
opengraph/opengraph.html
|
||||
opengraph/shortlink_linkrel.html
|
||||
opengraph/shorturl_link.html
|
||||
opengraph/shorturl_linkrel.html
|
||||
microformats.html
|
||||
share.html
|
||||
share_activate.html
|
||||
social_activate.html
|
||||
social_activate_basic.html
|
||||
social_activate_iframe.html
|
||||
social_postActivation.html
|
||||
!/browser/base/content/test/plugins/blockNoPlugins.xml
|
||||
|
||||
[browser_aboutHome_activation.js]
|
||||
[browser_addons.js]
|
||||
[browser_blocklist.js]
|
||||
tags = blocklist
|
||||
[browser_share.js]
|
||||
[browser_social_activation.js]
|
|
@ -1,224 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var SocialService = Cu.import("resource:///modules/SocialService.jsm", {}).SocialService;
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "AboutHomeUtils",
|
||||
"resource:///modules/AboutHome.jsm");
|
||||
|
||||
var snippet =
|
||||
" <script>" +
|
||||
" var manifest = {" +
|
||||
' "name": "Demo Social Service",' +
|
||||
' "origin": "https://example.com",' +
|
||||
' "iconURL": "chrome://branding/content/icon16.png",' +
|
||||
' "icon32URL": "chrome://branding/content/icon32.png",' +
|
||||
' "icon64URL": "chrome://branding/content/icon64.png",' +
|
||||
' "shareURL": "https://example.com/browser/browser/base/content/test/social/social_share.html",' +
|
||||
' "postActivationURL": "https://example.com/browser/browser/base/content/test/social/social_postActivation.html",' +
|
||||
" };" +
|
||||
" function activateProvider(node) {" +
|
||||
' node.setAttribute("data-service", JSON.stringify(manifest));' +
|
||||
' var event = new CustomEvent("ActivateSocialFeature");' +
|
||||
" node.dispatchEvent(event);" +
|
||||
" }" +
|
||||
" </script>" +
|
||||
' <div id="activationSnippet" onclick="activateProvider(this)">' +
|
||||
' <img src="chrome://branding/content/icon32.png"></img>' +
|
||||
" </div>";
|
||||
|
||||
// enable one-click activation
|
||||
var snippet2 =
|
||||
" <script>" +
|
||||
" var manifest = {" +
|
||||
' "name": "Demo Social Service",' +
|
||||
' "origin": "https://example.com",' +
|
||||
' "iconURL": "chrome://branding/content/icon16.png",' +
|
||||
' "icon32URL": "chrome://branding/content/icon32.png",' +
|
||||
' "icon64URL": "chrome://branding/content/icon64.png",' +
|
||||
' "shareURL": "https://example.com/browser/browser/base/content/test/social/social_share.html",' +
|
||||
' "postActivationURL": "https://example.com/browser/browser/base/content/test/social/social_postActivation.html",' +
|
||||
' "oneclick": true' +
|
||||
" };" +
|
||||
" function activateProvider(node) {" +
|
||||
' node.setAttribute("data-service", JSON.stringify(manifest));' +
|
||||
' var event = new CustomEvent("ActivateSocialFeature");' +
|
||||
" node.dispatchEvent(event);" +
|
||||
" }" +
|
||||
" </script>" +
|
||||
' <div id="activationSnippet" onclick="activateProvider(this)">' +
|
||||
' <img src="chrome://branding/content/icon32.png"></img>' +
|
||||
" </div>";
|
||||
|
||||
var gTests = [
|
||||
|
||||
{
|
||||
desc: "Test activation with enable panel",
|
||||
snippet,
|
||||
panel: true
|
||||
},
|
||||
|
||||
{
|
||||
desc: "Test activation bypassing enable panel",
|
||||
snippet: snippet2,
|
||||
panel: false
|
||||
}
|
||||
];
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
requestLongerTimeout(2);
|
||||
ignoreAllUncaughtExceptions();
|
||||
PopupNotifications.panel.setAttribute("animate", "false");
|
||||
registerCleanupFunction(function() {
|
||||
PopupNotifications.panel.removeAttribute("animate");
|
||||
});
|
||||
|
||||
(async function() {
|
||||
for (let testCase of gTests) {
|
||||
info(testCase.desc);
|
||||
|
||||
// Create a tab to run the test.
|
||||
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser);
|
||||
|
||||
// Add an event handler to modify the snippets map once it's ready.
|
||||
let snippetsPromise = promiseSetupSnippetsMap(tab, testCase.snippet);
|
||||
|
||||
// Start loading about:home and wait for it to complete, snippets should be loaded
|
||||
await promiseTabLoadEvent(tab, "about:home", "AboutHomeLoadSnippetsCompleted");
|
||||
|
||||
await snippetsPromise;
|
||||
|
||||
// ensure our activation snippet is indeed available
|
||||
await ContentTask.spawn(tab.linkedBrowser, {}, async function(arg) {
|
||||
ok(!!content.document.getElementById("snippets"), "Found snippets element");
|
||||
ok(!!content.document.getElementById("activationSnippet"), "The snippet is present.");
|
||||
});
|
||||
|
||||
await new Promise(resolve => {
|
||||
activateProvider(tab, testCase.panel).then(() => {
|
||||
checkSocialUI();
|
||||
SocialService.uninstallProvider("https://example.com", function() {
|
||||
info("provider uninstalled");
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// activation opened a post-activation info tab, close it.
|
||||
await BrowserTestUtils.removeTab(gBrowser.selectedTab);
|
||||
await BrowserTestUtils.removeTab(tab);
|
||||
}
|
||||
})().then(finish, ex => {
|
||||
ok(false, "Unexpected Exception: " + ex);
|
||||
finish();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a load in an existing tab and waits for it to finish (via some event).
|
||||
*
|
||||
* @param aTab
|
||||
* The tab to load into.
|
||||
* @param aUrl
|
||||
* The url to load.
|
||||
* @param aEvent
|
||||
* The load event type to wait for. Defaults to "load".
|
||||
* @return {Promise} resolved when the event is handled.
|
||||
*/
|
||||
function promiseTabLoadEvent(aTab, aURL, aEventType = "load") {
|
||||
return new Promise(resolve => {
|
||||
info("Wait tab event: " + aEventType);
|
||||
aTab.linkedBrowser.addEventListener(aEventType, function load(event) {
|
||||
if (event.originalTarget != aTab.linkedBrowser.contentDocument ||
|
||||
event.target.location.href == "about:blank") {
|
||||
info("skipping spurious load event");
|
||||
return;
|
||||
}
|
||||
aTab.linkedBrowser.removeEventListener(aEventType, load, true);
|
||||
info("Tab event received: " + aEventType);
|
||||
resolve();
|
||||
}, true, true);
|
||||
aTab.linkedBrowser.loadURI(aURL);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans up snippets and ensures that by default we don't try to check for
|
||||
* remote snippets since that may cause network bustage or slowness.
|
||||
*
|
||||
* @param aTab
|
||||
* The tab containing about:home.
|
||||
* @param aSetupFn
|
||||
* The setup function to be run.
|
||||
* @return {Promise} resolved when the snippets are ready. Gets the snippets map.
|
||||
*/
|
||||
function promiseSetupSnippetsMap(aTab, aSnippet) {
|
||||
info("Waiting for snippets map");
|
||||
|
||||
return ContentTask.spawn(aTab.linkedBrowser,
|
||||
{snippetsVersion: AboutHomeUtils.snippetsVersion,
|
||||
snippet: aSnippet},
|
||||
async function(arg) {
|
||||
return new Promise(resolve => {
|
||||
addEventListener("AboutHomeLoadSnippets", function load(event) {
|
||||
removeEventListener("AboutHomeLoadSnippets", load, true);
|
||||
|
||||
let cw = content.window.wrappedJSObject;
|
||||
|
||||
// The snippets should already be ready by this point. Here we're
|
||||
// just obtaining a reference to the snippets map.
|
||||
cw.ensureSnippetsMapThen(function(aSnippetsMap) {
|
||||
aSnippetsMap = Cu.waiveXrays(aSnippetsMap);
|
||||
console.log("Got snippets map: " +
|
||||
"{ last-update: " + aSnippetsMap.get("snippets-last-update") +
|
||||
", cached-version: " + aSnippetsMap.get("snippets-cached-version") +
|
||||
" }");
|
||||
// Don't try to update.
|
||||
aSnippetsMap.set("snippets-last-update", Date.now());
|
||||
aSnippetsMap.set("snippets-cached-version", arg.snippetsVersion);
|
||||
// Clear snippets.
|
||||
aSnippetsMap.delete("snippets");
|
||||
aSnippetsMap.set("snippets", arg.snippet);
|
||||
resolve();
|
||||
});
|
||||
}, true, true);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function sendActivationEvent(tab) {
|
||||
// hack Social.lastEventReceived so we don't hit the "too many events" check.
|
||||
Social.lastEventReceived = 0;
|
||||
let doc = tab.linkedBrowser.contentDocument;
|
||||
// if our test has a frame, use it
|
||||
if (doc.defaultView.frames[0])
|
||||
doc = doc.defaultView.frames[0].document;
|
||||
let button = doc.getElementById("activationSnippet");
|
||||
BrowserTestUtils.synthesizeMouseAtCenter(button, {}, tab.linkedBrowser);
|
||||
}
|
||||
|
||||
function activateProvider(tab, expectPanel, aCallback) {
|
||||
return new Promise(resolve => {
|
||||
if (expectPanel) {
|
||||
BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown").then(() => {
|
||||
let panel = document.getElementById("servicesInstall-notification");
|
||||
panel.button.click();
|
||||
});
|
||||
}
|
||||
waitForProviderLoad().then(() => {
|
||||
checkSocialUI();
|
||||
resolve();
|
||||
});
|
||||
sendActivationEvent(tab);
|
||||
});
|
||||
}
|
||||
|
||||
function waitForProviderLoad(cb) {
|
||||
return Promise.all([
|
||||
promiseObserverNotified("social:provider-enabled"),
|
||||
BrowserTestUtils.waitForNewTab(gBrowser, "https://example.com/browser/browser/base/content/test/social/social_postActivation.html"),
|
||||
]);
|
||||
}
|
|
@ -1,217 +0,0 @@
|
|||
var AddonManager = Cu.import("resource://gre/modules/AddonManager.jsm", {}).AddonManager;
|
||||
var SocialService = Cu.import("resource:///modules/SocialService.jsm", {}).SocialService;
|
||||
|
||||
var manifest = {
|
||||
name: "provider 1",
|
||||
origin: "https://example.com",
|
||||
shareURL: "https://example.com/browser/browser/base/content/test/social/social_share.html",
|
||||
iconURL: "https://example.com/browser/browser/base/content/test/general/moz.png"
|
||||
};
|
||||
var manifest2 = { // used for testing install
|
||||
name: "provider 2",
|
||||
origin: "https://test1.example.com",
|
||||
shareURL: "https://test1.example.com/browser/browser/base/content/test/social/social_share.html",
|
||||
iconURL: "https://test1.example.com/browser/browser/base/content/test/general/moz.png",
|
||||
version: "1.0"
|
||||
};
|
||||
var manifestUpgrade = { // used for testing install
|
||||
name: "provider 3",
|
||||
origin: "https://test2.example.com",
|
||||
shareURL: "https://test2.example.com/browser/browser/base/content/test/social/social_share.html",
|
||||
iconURL: "https://test2.example.com/browser/browser/base/content/test/general/moz.png",
|
||||
version: "1.0"
|
||||
};
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
PopupNotifications.panel.setAttribute("animate", "false");
|
||||
registerCleanupFunction(function() {
|
||||
PopupNotifications.panel.removeAttribute("animate");
|
||||
});
|
||||
|
||||
let prefname = getManifestPrefname(manifest);
|
||||
// ensure that manifest2 is NOT showing as builtin
|
||||
is(SocialService.getOriginActivationType(manifest.origin), "foreign", "manifest is foreign");
|
||||
is(SocialService.getOriginActivationType(manifest2.origin), "foreign", "manifest2 is foreign");
|
||||
|
||||
Services.prefs.setBoolPref("social.remote-install.enabled", true);
|
||||
runSocialTests(tests, undefined, undefined, function() {
|
||||
Services.prefs.clearUserPref("social.remote-install.enabled");
|
||||
ok(!Services.prefs.prefHasUserValue(prefname), "manifest is not in user-prefs");
|
||||
// just in case the tests failed, clear these here as well
|
||||
Services.prefs.clearUserPref("social.directories");
|
||||
finish();
|
||||
});
|
||||
}
|
||||
|
||||
function installListener(next, aManifest) {
|
||||
let expectEvent = "onInstalling";
|
||||
let prefname = getManifestPrefname(aManifest);
|
||||
// wait for the actual removal to call next
|
||||
SocialService.registerProviderListener(function providerListener(topic, origin, providers) {
|
||||
if (topic == "provider-disabled") {
|
||||
SocialService.unregisterProviderListener(providerListener);
|
||||
is(origin, aManifest.origin, "provider disabled");
|
||||
executeSoon(next);
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
onInstalling(addon) {
|
||||
is(expectEvent, "onInstalling", "install started");
|
||||
is(addon.manifest.origin, aManifest.origin, "provider about to be installed");
|
||||
ok(!Services.prefs.prefHasUserValue(prefname), "manifest is not in user-prefs");
|
||||
expectEvent = "onInstalled";
|
||||
},
|
||||
onInstalled(addon) {
|
||||
is(addon.manifest.origin, aManifest.origin, "provider installed");
|
||||
ok(addon.installDate.getTime() > 0, "addon has installDate");
|
||||
ok(addon.updateDate.getTime() > 0, "addon has updateDate");
|
||||
ok(Services.prefs.prefHasUserValue(prefname), "manifest is in user-prefs");
|
||||
expectEvent = "onUninstalling";
|
||||
},
|
||||
onUninstalling(addon) {
|
||||
is(expectEvent, "onUninstalling", "uninstall started");
|
||||
is(addon.manifest.origin, aManifest.origin, "provider about to be uninstalled");
|
||||
ok(Services.prefs.prefHasUserValue(prefname), "manifest is in user-prefs");
|
||||
expectEvent = "onUninstalled";
|
||||
},
|
||||
onUninstalled(addon) {
|
||||
is(expectEvent, "onUninstalled", "provider has been uninstalled");
|
||||
is(addon.manifest.origin, aManifest.origin, "provider uninstalled");
|
||||
ok(!Services.prefs.prefHasUserValue(prefname), "manifest is not in user-prefs");
|
||||
AddonManager.removeAddonListener(this);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
var tests = {
|
||||
testHTTPInstallFailure(next) {
|
||||
let installFrom = "http://example.com";
|
||||
is(SocialService.getOriginActivationType(installFrom), "foreign", "testing foriegn install");
|
||||
let data = {
|
||||
origin: installFrom,
|
||||
url: installFrom + "/activate",
|
||||
manifest,
|
||||
window
|
||||
}
|
||||
Social.installProvider(data, function(addonManifest) {
|
||||
ok(!addonManifest, "unable to install provider over http");
|
||||
next();
|
||||
});
|
||||
},
|
||||
testAddonEnableToggle(next) {
|
||||
let expectEvent;
|
||||
let prefname = getManifestPrefname(manifest);
|
||||
let listener = {
|
||||
onEnabled(addon) {
|
||||
is(expectEvent, "onEnabled", "provider onEnabled");
|
||||
ok(!addon.userDisabled, "provider enabled");
|
||||
executeSoon(function() {
|
||||
expectEvent = "onDisabling";
|
||||
addon.userDisabled = true;
|
||||
});
|
||||
},
|
||||
onEnabling(addon) {
|
||||
is(expectEvent, "onEnabling", "provider onEnabling");
|
||||
expectEvent = "onEnabled";
|
||||
},
|
||||
onDisabled(addon) {
|
||||
is(expectEvent, "onDisabled", "provider onDisabled");
|
||||
ok(addon.userDisabled, "provider disabled");
|
||||
AddonManager.removeAddonListener(listener);
|
||||
// clear the provider user-level pref
|
||||
Services.prefs.clearUserPref(prefname);
|
||||
executeSoon(next);
|
||||
},
|
||||
onDisabling(addon) {
|
||||
is(expectEvent, "onDisabling", "provider onDisabling");
|
||||
expectEvent = "onDisabled";
|
||||
}
|
||||
};
|
||||
AddonManager.addAddonListener(listener);
|
||||
|
||||
// we're only testing enable disable, so we quickly set the user-level pref
|
||||
// for this provider and test enable/disable toggling
|
||||
setManifestPref(prefname, manifest);
|
||||
ok(Services.prefs.prefHasUserValue(prefname), "manifest is in user-prefs");
|
||||
AddonManager.getAddonsByTypes(["service"], function(addons) {
|
||||
for (let addon of addons) {
|
||||
if (addon.userDisabled) {
|
||||
expectEvent = "onEnabling";
|
||||
addon.userDisabled = false;
|
||||
// only test with one addon
|
||||
return;
|
||||
}
|
||||
}
|
||||
ok(false, "no addons toggled");
|
||||
next();
|
||||
});
|
||||
},
|
||||
testProviderEnableToggle(next) {
|
||||
// enable and disabel a provider from the SocialService interface, check
|
||||
// that the addon manager is updated
|
||||
|
||||
let expectEvent;
|
||||
let prefname = getManifestPrefname(manifest);
|
||||
|
||||
let listener = {
|
||||
onEnabled(addon) {
|
||||
is(expectEvent, "onEnabled", "provider onEnabled");
|
||||
is(addon.manifest.origin, manifest.origin, "provider enabled");
|
||||
ok(!addon.userDisabled, "provider !userDisabled");
|
||||
},
|
||||
onEnabling(addon) {
|
||||
is(expectEvent, "onEnabling", "provider onEnabling");
|
||||
is(addon.manifest.origin, manifest.origin, "provider about to be enabled");
|
||||
expectEvent = "onEnabled";
|
||||
},
|
||||
onDisabled(addon) {
|
||||
is(expectEvent, "onDisabled", "provider onDisabled");
|
||||
is(addon.manifest.origin, manifest.origin, "provider disabled");
|
||||
ok(addon.userDisabled, "provider userDisabled");
|
||||
},
|
||||
onDisabling(addon) {
|
||||
is(expectEvent, "onDisabling", "provider onDisabling");
|
||||
is(addon.manifest.origin, manifest.origin, "provider about to be disabled");
|
||||
expectEvent = "onDisabled";
|
||||
}
|
||||
};
|
||||
AddonManager.addAddonListener(listener);
|
||||
|
||||
expectEvent = "onEnabling";
|
||||
setManifestPref(prefname, manifest);
|
||||
SocialService.enableProvider(manifest.origin, function(provider) {
|
||||
expectEvent = "onDisabling";
|
||||
SocialService.disableProvider(provider.origin, function() {
|
||||
AddonManager.removeAddonListener(listener);
|
||||
Services.prefs.clearUserPref(prefname);
|
||||
next();
|
||||
});
|
||||
});
|
||||
},
|
||||
testDirectoryInstall(next) {
|
||||
AddonManager.addAddonListener(installListener(next, manifest2));
|
||||
|
||||
BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown").then(() => {
|
||||
let panel = document.getElementById("servicesInstall-notification");
|
||||
info("servicesInstall-notification panel opened");
|
||||
panel.button.click();
|
||||
});
|
||||
|
||||
Services.prefs.setCharPref("social.directories", manifest2.origin);
|
||||
is(SocialService.getOriginActivationType(manifest2.origin), "directory", "testing directory install");
|
||||
let data = {
|
||||
origin: manifest2.origin,
|
||||
url: manifest2.origin + "/directory",
|
||||
manifest: manifest2,
|
||||
window
|
||||
}
|
||||
Social.installProvider(data, function(addonManifest) {
|
||||
Services.prefs.clearUserPref("social.directories");
|
||||
SocialService.enableProvider(addonManifest.origin, function(provider) {
|
||||
Social.uninstallProvider(addonManifest.origin);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,208 +0,0 @@
|
|||
/* 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/. */
|
||||
|
||||
// a place for miscellaneous social tests
|
||||
|
||||
var SocialService = Cu.import("resource:///modules/SocialService.jsm", {}).SocialService;
|
||||
|
||||
const URI_EXTENSION_BLOCKLIST_DIALOG = "chrome://mozapps/content/extensions/blocklist.xul";
|
||||
var blocklistURL = "http://example.com/browser/browser/base/content/test/social/blocklist.xml";
|
||||
|
||||
var manifest = { // normal provider
|
||||
name: "provider ok",
|
||||
origin: "https://example.com",
|
||||
shareURL: "https://example.com/browser/browser/base/content/test/social/social_share.html",
|
||||
iconURL: "https://example.com/browser/browser/base/content/test/general/moz.png"
|
||||
};
|
||||
var manifest_bad = { // normal provider
|
||||
name: "provider blocked",
|
||||
origin: "https://test1.example.com",
|
||||
shareURL: "https://test1.example.com/browser/browser/base/content/test/social/social_share.html",
|
||||
iconURL: "https://test1.example.com/browser/browser/base/content/test/general/moz.png"
|
||||
};
|
||||
|
||||
// blocklist testing
|
||||
function updateBlocklist() {
|
||||
var blocklistNotifier = Cc["@mozilla.org/extensions/blocklist;1"]
|
||||
.getService(Ci.nsITimerCallback);
|
||||
let promise = promiseObserverNotified("blocklist-updated");
|
||||
blocklistNotifier.notify(null);
|
||||
return promise;
|
||||
}
|
||||
|
||||
var _originalTestBlocklistURL = null;
|
||||
function setAndUpdateBlocklist(aURL) {
|
||||
if (!_originalTestBlocklistURL)
|
||||
_originalTestBlocklistURL = Services.prefs.getCharPref("extensions.blocklist.url");
|
||||
Services.prefs.setCharPref("extensions.blocklist.url", aURL);
|
||||
return updateBlocklist();
|
||||
}
|
||||
|
||||
function resetBlocklist() {
|
||||
// XXX - this has "forked" from the head.js helpers in our parent directory :(
|
||||
// But let's reuse their blockNoPlugins.xml. Later, we should arrange to
|
||||
// use their head.js helpers directly
|
||||
let noBlockedURL = "http://example.com/browser/browser/base/content/test/plugins/blockNoPlugins.xml";
|
||||
return new Promise(resolve => {
|
||||
setAndUpdateBlocklist(noBlockedURL).then(() => {
|
||||
Services.prefs.setCharPref("extensions.blocklist.url", _originalTestBlocklistURL);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
// turn on logging for nsBlocklistService.js
|
||||
Services.prefs.setBoolPref("extensions.logging.enabled", true);
|
||||
registerCleanupFunction(function() {
|
||||
Services.prefs.clearUserPref("extensions.logging.enabled");
|
||||
});
|
||||
|
||||
runSocialTests(tests, undefined, undefined, function() {
|
||||
resetBlocklist().then(finish); // restore to original pref
|
||||
});
|
||||
}
|
||||
|
||||
var tests = {
|
||||
testSimpleBlocklist(next) {
|
||||
// this really just tests adding and clearing our blocklist for later tests
|
||||
setAndUpdateBlocklist(blocklistURL).then(() => {
|
||||
ok(Services.blocklist.isAddonBlocklisted(SocialService.createWrapper(manifest_bad)), "blocking 'blocked'");
|
||||
ok(!Services.blocklist.isAddonBlocklisted(SocialService.createWrapper(manifest)), "not blocking 'good'");
|
||||
resetBlocklist().then(() => {
|
||||
ok(!Services.blocklist.isAddonBlocklisted(SocialService.createWrapper(manifest_bad)), "blocklist cleared");
|
||||
next();
|
||||
});
|
||||
});
|
||||
},
|
||||
testAddingNonBlockedProvider(next) {
|
||||
function finishTest(isgood) {
|
||||
ok(isgood, "adding non-blocked provider ok");
|
||||
Services.prefs.clearUserPref("social.manifest.good");
|
||||
resetBlocklist().then(next);
|
||||
}
|
||||
setManifestPref("social.manifest.good", manifest);
|
||||
setAndUpdateBlocklist(blocklistURL).then(() => {
|
||||
try {
|
||||
SocialService.addProvider(manifest, function(provider) {
|
||||
try {
|
||||
SocialService.disableProvider(provider.origin, function() {
|
||||
ok(true, "added and removed provider");
|
||||
finishTest(true);
|
||||
});
|
||||
} catch (e) {
|
||||
ok(false, "SocialService.disableProvider threw exception: " + e);
|
||||
finishTest(false);
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
ok(false, "SocialService.addProvider threw exception: " + e);
|
||||
finishTest(false);
|
||||
}
|
||||
});
|
||||
},
|
||||
testAddingBlockedProvider(next) {
|
||||
function finishTest(good) {
|
||||
ok(good, "Unable to add blocklisted provider");
|
||||
Services.prefs.clearUserPref("social.manifest.blocked");
|
||||
resetBlocklist().then(next);
|
||||
}
|
||||
setManifestPref("social.manifest.blocked", manifest_bad);
|
||||
setAndUpdateBlocklist(blocklistURL).then(() => {
|
||||
try {
|
||||
SocialService.addProvider(manifest_bad, function(provider) {
|
||||
SocialService.disableProvider(provider.origin, function() {
|
||||
ok(false, "SocialService.addProvider should throw blocklist exception");
|
||||
finishTest(false);
|
||||
});
|
||||
});
|
||||
} catch (e) {
|
||||
ok(true, "SocialService.addProvider should throw blocklist exception: " + e);
|
||||
finishTest(true);
|
||||
}
|
||||
});
|
||||
},
|
||||
testInstallingBlockedProvider(next) {
|
||||
function finishTest(good) {
|
||||
ok(good, "Unable to install blocklisted provider");
|
||||
resetBlocklist().then(next);
|
||||
}
|
||||
let activationURL = manifest_bad.origin + "/browser/browser/base/content/test/social/social_activate.html"
|
||||
setAndUpdateBlocklist(blocklistURL).then(() => {
|
||||
try {
|
||||
// expecting an exception when attempting to install a hard blocked
|
||||
// provider
|
||||
let data = {
|
||||
origin: manifest_bad.origin,
|
||||
url: activationURL,
|
||||
manifest: manifest_bad,
|
||||
window
|
||||
}
|
||||
Social.installProvider(data, function(addonManifest) {
|
||||
finishTest(false);
|
||||
});
|
||||
} catch (e) {
|
||||
finishTest(true);
|
||||
}
|
||||
});
|
||||
},
|
||||
testBlockingExistingProvider(next) {
|
||||
let listener = {
|
||||
_window: null,
|
||||
onOpenWindow(aXULWindow) {
|
||||
Services.wm.removeListener(this);
|
||||
this._window = aXULWindow;
|
||||
let domwindow = aXULWindow.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindow);
|
||||
|
||||
domwindow.addEventListener("load", function() {
|
||||
domwindow.addEventListener("unload", function() {
|
||||
info("blocklist window was closed");
|
||||
Services.wm.removeListener(listener);
|
||||
next();
|
||||
}, {once: true});
|
||||
|
||||
is(domwindow.document.location.href, URI_EXTENSION_BLOCKLIST_DIALOG, "dialog opened and focused");
|
||||
// wait until after load to cancel so the dialog has initalized. we
|
||||
// don't want to accept here since that restarts the browser.
|
||||
executeSoon(() => {
|
||||
let cancelButton = domwindow.document.documentElement.getButton("cancel");
|
||||
info("***** hit the cancel button\n");
|
||||
cancelButton.doCommand();
|
||||
});
|
||||
}, {once: true});
|
||||
},
|
||||
onCloseWindow(aXULWindow) { },
|
||||
onWindowTitleChange(aXULWindow, aNewTitle) { }
|
||||
};
|
||||
|
||||
Services.wm.addListener(listener);
|
||||
|
||||
setManifestPref("social.manifest.blocked", manifest_bad);
|
||||
try {
|
||||
SocialService.addProvider(manifest_bad, function(provider) {
|
||||
// the act of blocking should cause a 'provider-disabled' notification
|
||||
// from SocialService.
|
||||
SocialService.registerProviderListener(function providerListener(topic, origin, providers) {
|
||||
if (topic != "provider-disabled")
|
||||
return;
|
||||
SocialService.unregisterProviderListener(providerListener);
|
||||
is(origin, provider.origin, "provider disabled");
|
||||
SocialService.getProvider(provider.origin, function(p) {
|
||||
ok(p == null, "blocklisted provider disabled");
|
||||
Services.prefs.clearUserPref("social.manifest.blocked");
|
||||
resetBlocklist();
|
||||
});
|
||||
});
|
||||
// no callback - the act of updating should cause the listener above
|
||||
// to fire.
|
||||
setAndUpdateBlocklist(blocklistURL);
|
||||
});
|
||||
} catch (e) {
|
||||
ok(false, "unable to add provider " + e);
|
||||
next();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,396 +0,0 @@
|
|||
/* eslint-env mozilla/frame-script */
|
||||
|
||||
var SocialService = Cu.import("resource:///modules/SocialService.jsm", {}).SocialService;
|
||||
|
||||
var baseURL = "https://example.com/browser/browser/base/content/test/social/";
|
||||
|
||||
var manifest = { // normal provider
|
||||
name: "provider 1",
|
||||
origin: "https://example.com",
|
||||
iconURL: "https://example.com/browser/browser/base/content/test/general/moz.png",
|
||||
shareURL: "https://example.com/browser/browser/base/content/test/social/share.html"
|
||||
};
|
||||
var activationPage = "https://example.com/browser/browser/base/content/test/social/share_activate.html";
|
||||
|
||||
function sendActivationEvent(subframe) {
|
||||
// hack Social.lastEventReceived so we don't hit the "too many events" check.
|
||||
Social.lastEventReceived = 0;
|
||||
let doc = subframe.contentDocument;
|
||||
// if our test has a frame, use it
|
||||
let button = doc.getElementById("activation");
|
||||
ok(!!button, "got the activation button");
|
||||
EventUtils.synthesizeMouseAtCenter(button, {}, doc.defaultView);
|
||||
}
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
Services.prefs.setCharPref("social.shareDirectory", activationPage);
|
||||
|
||||
let frameScript = "data:,(" + function frame_script() {
|
||||
addEventListener("OpenGraphData", function(aEvent) {
|
||||
sendAsyncMessage("sharedata", aEvent.detail);
|
||||
}, true, true);
|
||||
/* bug 1042991, ensure history is available by calling history.back on close */
|
||||
addMessageListener("closeself", function(e) {
|
||||
content.history.back();
|
||||
content.close();
|
||||
}, true);
|
||||
/* if text is entered into field, onbeforeunload will cause a modal dialog
|
||||
unless dialogs have been disabled for the iframe. */
|
||||
content.onbeforeunload = function(e) {
|
||||
return "FAIL.";
|
||||
};
|
||||
}.toString() + ")();";
|
||||
let mm = window.getGroupMessageManager("social");
|
||||
mm.loadFrameScript(frameScript, true);
|
||||
|
||||
// Animation on the panel can cause intermittent failures such as bug 1115131.
|
||||
SocialShare.panel.setAttribute("animate", "false");
|
||||
registerCleanupFunction(function() {
|
||||
SocialShare.panel.removeAttribute("animate");
|
||||
mm.removeDelayedFrameScript(frameScript);
|
||||
Services.prefs.clearUserPref("social.directories");
|
||||
Services.prefs.clearUserPref("social.shareDirectory");
|
||||
Services.prefs.clearUserPref("social.share.activationPanelEnabled");
|
||||
});
|
||||
runSocialTests(tests, undefined, function(next) {
|
||||
let shareButton = SocialShare.shareButton;
|
||||
if (shareButton) {
|
||||
CustomizableUI.removeWidgetFromArea("social-share-button", CustomizableUI.AREA_NAVBAR)
|
||||
shareButton.remove();
|
||||
}
|
||||
next();
|
||||
});
|
||||
}
|
||||
|
||||
var corpus = [
|
||||
{
|
||||
url: baseURL + "opengraph/opengraph.html",
|
||||
options: {
|
||||
// og:title
|
||||
title: ">This is my title<",
|
||||
// og:description
|
||||
description: "A test corpus file for open graph tags we care about",
|
||||
// medium: this.getPageMedium(),
|
||||
// source: this.getSourceURL(),
|
||||
// og:url
|
||||
url: "https://www.mozilla.org/",
|
||||
// shortUrl: this.getShortURL(),
|
||||
// og:image
|
||||
previews: ["https://www.mozilla.org/favicon.png"],
|
||||
// og:site_name
|
||||
siteName: ">My simple test page<"
|
||||
}
|
||||
},
|
||||
{
|
||||
// tests that og:url doesn't override the page url if it is bad
|
||||
url: baseURL + "opengraph/og_invalid_url.html",
|
||||
options: {
|
||||
description: "A test corpus file for open graph tags passing a bad url",
|
||||
url: baseURL + "opengraph/og_invalid_url.html",
|
||||
previews: [],
|
||||
siteName: "Evil chrome delivering website"
|
||||
}
|
||||
},
|
||||
{
|
||||
url: baseURL + "opengraph/shorturl_link.html",
|
||||
options: {
|
||||
previews: ["http://example.com/1234/56789.jpg"],
|
||||
url: "http://www.example.com/photos/56789/",
|
||||
shortUrl: "http://imshort/p/abcde"
|
||||
}
|
||||
},
|
||||
{
|
||||
url: baseURL + "opengraph/shorturl_linkrel.html",
|
||||
options: {
|
||||
previews: ["http://example.com/1234/56789.jpg"],
|
||||
url: "http://www.example.com/photos/56789/",
|
||||
shortUrl: "http://imshort/p/abcde"
|
||||
}
|
||||
},
|
||||
{
|
||||
url: baseURL + "opengraph/shortlink_linkrel.html",
|
||||
options: {
|
||||
previews: ["http://example.com/1234/56789.jpg"],
|
||||
url: "http://www.example.com/photos/56789/",
|
||||
shortUrl: "http://imshort/p/abcde"
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
function hasoptions(testOptions, options) {
|
||||
for (let option in testOptions) {
|
||||
let data = testOptions[option];
|
||||
info("data: " + JSON.stringify(data));
|
||||
let message_data = options[option];
|
||||
info("message_data: " + JSON.stringify(message_data));
|
||||
if (Array.isArray(data)) {
|
||||
// the message may have more array elements than we are testing for, this
|
||||
// is ok since some of those are hard to test. So we just test that
|
||||
// anything in our test data IS in the message.
|
||||
ok(Array.every(data, function(item) { return message_data.indexOf(item) >= 0 }), "option " + option);
|
||||
} else {
|
||||
is(message_data, data, "option " + option);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var tests = {
|
||||
testShareDisabledOnActivation(next) {
|
||||
// starting on about:blank page, share should be visible but disabled when
|
||||
// adding provider
|
||||
is(gBrowser.currentURI.spec, "about:blank");
|
||||
|
||||
// initialize the button into the navbar
|
||||
CustomizableUI.addWidgetToArea("social-share-button", CustomizableUI.AREA_NAVBAR);
|
||||
// ensure correct state
|
||||
SocialUI.onCustomizeEnd(window);
|
||||
|
||||
SocialService.addProvider(manifest, function(provider) {
|
||||
is(SocialUI.enabled, true, "SocialUI is enabled");
|
||||
checkSocialUI();
|
||||
// share should not be enabled since we only have about:blank page
|
||||
let shareButton = SocialShare.shareButton;
|
||||
// verify the attribute for proper css
|
||||
is(shareButton.getAttribute("disabled"), "true", "share button attribute is disabled");
|
||||
// button should be visible
|
||||
is(shareButton.hidden, false, "share button is visible");
|
||||
SocialService.disableProvider(manifest.origin, next);
|
||||
});
|
||||
},
|
||||
testShareEnabledOnActivation(next) {
|
||||
// starting from *some* page, share should be visible and enabled when
|
||||
// activating provider
|
||||
// initialize the button into the navbar
|
||||
CustomizableUI.addWidgetToArea("social-share-button", CustomizableUI.AREA_NAVBAR);
|
||||
// ensure correct state
|
||||
SocialUI.onCustomizeEnd(window);
|
||||
|
||||
let testData = corpus[0];
|
||||
BrowserTestUtils.openNewForegroundTab(gBrowser, testData.url).then(tab => {
|
||||
SocialService.addProvider(manifest, function(provider) {
|
||||
is(SocialUI.enabled, true, "SocialUI is enabled");
|
||||
checkSocialUI();
|
||||
// share should not be enabled since we only have about:blank page
|
||||
let shareButton = SocialShare.shareButton;
|
||||
// verify the attribute for proper css
|
||||
ok(!shareButton.hasAttribute("disabled"), "share button is enabled");
|
||||
// button should be visible
|
||||
is(shareButton.hidden, false, "share button is visible");
|
||||
BrowserTestUtils.removeTab(tab).then(next);
|
||||
});
|
||||
});
|
||||
},
|
||||
testSharePage(next) {
|
||||
let testTab;
|
||||
let testIndex = 0;
|
||||
let testData = corpus[testIndex++];
|
||||
|
||||
// initialize the button into the navbar
|
||||
CustomizableUI.addWidgetToArea("social-share-button", CustomizableUI.AREA_NAVBAR);
|
||||
// ensure correct state
|
||||
SocialUI.onCustomizeEnd(window);
|
||||
|
||||
let mm = window.getGroupMessageManager("social");
|
||||
mm.addMessageListener("sharedata", function handler(msg) {
|
||||
BrowserTestUtils.removeTab(testTab).then(() => {
|
||||
hasoptions(testData.options, JSON.parse(msg.data));
|
||||
testData = corpus[testIndex++];
|
||||
BrowserTestUtils.waitForCondition(() => { return SocialShare.currentShare == null; }, "share panel closed").then(() => {
|
||||
if (testData) {
|
||||
runOneTest();
|
||||
} else {
|
||||
mm.removeMessageListener("sharedata", handler);
|
||||
SocialService.disableProvider(manifest.origin, next);
|
||||
}
|
||||
});
|
||||
SocialShare.iframe.messageManager.sendAsyncMessage("closeself", {});
|
||||
});
|
||||
});
|
||||
|
||||
function runOneTest() {
|
||||
BrowserTestUtils.openNewForegroundTab(gBrowser, testData.url).then(tab => {
|
||||
testTab = tab;
|
||||
|
||||
let shareButton = SocialShare.shareButton;
|
||||
// verify the attribute for proper css
|
||||
ok(!shareButton.hasAttribute("disabled"), "share button is enabled");
|
||||
// button should be visible
|
||||
is(shareButton.hidden, false, "share button is visible");
|
||||
|
||||
SocialShare.sharePage(manifest.origin);
|
||||
});
|
||||
}
|
||||
executeSoon(runOneTest);
|
||||
},
|
||||
testShareMicroformats(next) {
|
||||
// initialize the button into the navbar
|
||||
CustomizableUI.addWidgetToArea("social-share-button", CustomizableUI.AREA_NAVBAR);
|
||||
// ensure correct state
|
||||
SocialUI.onCustomizeEnd(window);
|
||||
|
||||
SocialService.addProvider(manifest, function(provider) {
|
||||
let target, testTab;
|
||||
|
||||
let expecting = JSON.stringify({
|
||||
"url": "https://example.com/browser/browser/base/content/test/social/microformats.html",
|
||||
"title": "Raspberry Pi Page",
|
||||
"previews": ["https://example.com/someimage.jpg"],
|
||||
"microformats": {
|
||||
"items": [{
|
||||
"type": ["h-product"],
|
||||
"properties": {
|
||||
"name": ["Raspberry Pi"],
|
||||
"photo": ["https://example.com/someimage.jpg"],
|
||||
"description": [{
|
||||
"value": "The Raspberry Pi is a credit-card sized computer that plugs into your TV and a keyboard. It's a capable little PC which can be used for many of the things that your desktop PC does, like spreadsheets, word-processing and games. It also plays high-definition video. We want to see it being used by kids all over the world to learn programming.",
|
||||
"html": "The Raspberry Pi is a credit-card sized computer that plugs into your TV and a keyboard. It's a capable little PC which can be used for many of the things that your desktop PC does, like spreadsheets, word-processing and games. It also plays high-definition video. We want to see it being used by kids all over the world to learn programming."
|
||||
}
|
||||
],
|
||||
"url": ["https://example.com/"],
|
||||
"price": ["29.95"],
|
||||
"review": [{
|
||||
"value": "4.5 out of 5",
|
||||
"type": ["h-review"],
|
||||
"properties": {
|
||||
"rating": ["4.5"]
|
||||
}
|
||||
}
|
||||
],
|
||||
"category": ["Computer", "Education"]
|
||||
}
|
||||
}
|
||||
],
|
||||
"rels": {
|
||||
"tag": ["https://example.com/wiki/computer", "https://example.com/wiki/education"]
|
||||
},
|
||||
"rel-urls": {
|
||||
"https://example.com/wiki/computer": {
|
||||
"text": "Computer",
|
||||
"rels": ["tag"]
|
||||
},
|
||||
"https://example.com/wiki/education": {
|
||||
"text": "Education",
|
||||
"rels": ["tag"]
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let mm = window.getGroupMessageManager("social");
|
||||
mm.addMessageListener("sharedata", function handler(msg) {
|
||||
is(msg.data, expecting, "microformats data ok");
|
||||
BrowserTestUtils.waitForCondition(() => { return SocialShare.currentShare == null; },
|
||||
"share panel closed").then(() => {
|
||||
mm.removeMessageListener("sharedata", handler);
|
||||
BrowserTestUtils.removeTab(testTab).then(() => {
|
||||
SocialService.disableProvider(manifest.origin, next);
|
||||
});
|
||||
});
|
||||
SocialShare.iframe.messageManager.sendAsyncMessage("closeself", {});
|
||||
});
|
||||
|
||||
let url = "https://example.com/browser/browser/base/content/test/social/microformats.html"
|
||||
BrowserTestUtils.openNewForegroundTab(gBrowser, url).then(tab => {
|
||||
testTab = tab;
|
||||
|
||||
let shareButton = SocialShare.shareButton;
|
||||
// verify the attribute for proper css
|
||||
ok(!shareButton.hasAttribute("disabled"), "share button is enabled");
|
||||
// button should be visible
|
||||
is(shareButton.hidden, false, "share button is visible");
|
||||
|
||||
let doc = tab.linkedBrowser.contentDocument;
|
||||
target = doc.getElementById("simple-hcard");
|
||||
SocialShare.sharePage(manifest.origin, null, target);
|
||||
});
|
||||
});
|
||||
},
|
||||
testSharePanelActivation(next) {
|
||||
let testTab;
|
||||
// cleared in the cleanup function
|
||||
Services.prefs.setCharPref("social.directories", "https://example.com");
|
||||
Services.prefs.setBoolPref("social.share.activationPanelEnabled", true);
|
||||
// make the iframe so we can wait on the load
|
||||
SocialShare._createFrame();
|
||||
let iframe = SocialShare.iframe;
|
||||
|
||||
// initialize the button into the navbar
|
||||
CustomizableUI.addWidgetToArea("social-share-button", CustomizableUI.AREA_NAVBAR);
|
||||
// ensure correct state
|
||||
SocialUI.onCustomizeEnd(window);
|
||||
|
||||
ensureFrameLoaded(iframe).then(() => {
|
||||
let subframe = iframe.contentDocument.getElementById("activation-frame");
|
||||
ensureFrameLoaded(subframe, activationPage).then(() => {
|
||||
is(subframe.contentDocument.location.href, activationPage, "activation page loaded");
|
||||
promiseObserverNotified("social:provider-enabled").then(() => {
|
||||
let mm = window.getGroupMessageManager("social");
|
||||
mm.addMessageListener("sharedata", function handler(msg) {
|
||||
ok(true, "share completed");
|
||||
|
||||
BrowserTestUtils.waitForCondition(() => { return SocialShare.currentShare == null; },
|
||||
"share panel closed").then(() => {
|
||||
BrowserTestUtils.removeTab(testTab).then(() => {
|
||||
mm.removeMessageListener("sharedata", handler);
|
||||
SocialService.uninstallProvider(manifest.origin, next);
|
||||
});
|
||||
});
|
||||
SocialShare.iframe.messageManager.sendAsyncMessage("closeself", {});
|
||||
});
|
||||
});
|
||||
sendActivationEvent(subframe);
|
||||
});
|
||||
});
|
||||
BrowserTestUtils.openNewForegroundTab(gBrowser, activationPage).then(tab => {
|
||||
let shareButton = SocialShare.shareButton;
|
||||
// verify the attribute for proper css
|
||||
ok(!shareButton.hasAttribute("disabled"), "share button is enabled");
|
||||
// button should be visible
|
||||
is(shareButton.hidden, false, "share button is visible");
|
||||
|
||||
testTab = tab;
|
||||
SocialShare.sharePage();
|
||||
});
|
||||
},
|
||||
testSharePanelDialog(next) {
|
||||
let testTab;
|
||||
// initialize the button into the navbar
|
||||
CustomizableUI.addWidgetToArea("social-share-button", CustomizableUI.AREA_NAVBAR);
|
||||
// ensure correct state
|
||||
SocialUI.onCustomizeEnd(window);
|
||||
SocialShare._createFrame();
|
||||
|
||||
SocialService.addProvider(manifest, () => {
|
||||
BrowserTestUtils.openNewForegroundTab(gBrowser, activationPage).then(tab => {
|
||||
ensureFrameLoaded(SocialShare.iframe).then(() => {
|
||||
// send keys to the input field. An unexpected failure will happen
|
||||
// if the onbeforeunload handler is fired.
|
||||
EventUtils.sendKey("f");
|
||||
EventUtils.sendKey("a");
|
||||
EventUtils.sendKey("i");
|
||||
EventUtils.sendKey("l");
|
||||
|
||||
SocialShare.panel.addEventListener("popuphidden", function(evt) {
|
||||
let topwin = Services.wm.getMostRecentWindow(null);
|
||||
is(topwin, window, "no dialog is open");
|
||||
|
||||
BrowserTestUtils.removeTab(testTab).then(() => {
|
||||
SocialService.disableProvider(manifest.origin, next);
|
||||
});
|
||||
}, {once: true});
|
||||
SocialShare.iframe.messageManager.sendAsyncMessage("closeself", {});
|
||||
});
|
||||
|
||||
let shareButton = SocialShare.shareButton;
|
||||
// verify the attribute for proper css
|
||||
ok(!shareButton.hasAttribute("disabled"), "share button is enabled");
|
||||
// button should be visible
|
||||
is(shareButton.hidden, false, "share button is visible");
|
||||
|
||||
testTab = tab;
|
||||
SocialShare.sharePage();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,274 +0,0 @@
|
|||
/* 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/. */
|
||||
|
||||
var SocialService = Cu.import("resource:///modules/SocialService.jsm", {}).SocialService;
|
||||
|
||||
var tabsToRemove = [];
|
||||
|
||||
function removeProvider(provider) {
|
||||
return new Promise(resolve => {
|
||||
// a full install sets the manifest into a pref, addProvider alone doesn't,
|
||||
// make sure we uninstall if the manifest was added.
|
||||
if (provider.manifest) {
|
||||
SocialService.uninstallProvider(provider.origin, resolve);
|
||||
} else {
|
||||
SocialService.disableProvider(provider.origin, resolve);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function postTestCleanup(callback) {
|
||||
(async function() {
|
||||
// any tabs opened by the test.
|
||||
for (let tab of tabsToRemove) {
|
||||
await BrowserTestUtils.removeTab(tab);
|
||||
}
|
||||
tabsToRemove = [];
|
||||
// all the providers may have been added.
|
||||
while (Social.providers.length > 0) {
|
||||
await removeProvider(Social.providers[0]);
|
||||
}
|
||||
})().then(callback);
|
||||
}
|
||||
|
||||
function newTab(url) {
|
||||
return new Promise(resolve => {
|
||||
BrowserTestUtils.openNewForegroundTab(gBrowser, url).then(tab => {
|
||||
tabsToRemove.push(tab);
|
||||
resolve(tab);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function sendActivationEvent(tab, callback, nullManifest) {
|
||||
// hack Social.lastEventReceived so we don't hit the "too many events" check.
|
||||
Social.lastEventReceived = 0;
|
||||
BrowserTestUtils.synthesizeMouseAtCenter("#activation", {}, tab.linkedBrowser);
|
||||
executeSoon(callback);
|
||||
}
|
||||
|
||||
function activateProvider(domain, callback, nullManifest) {
|
||||
let activationURL = domain + "/browser/browser/base/content/test/social/social_activate_basic.html"
|
||||
newTab(activationURL).then(tab => {
|
||||
sendActivationEvent(tab, callback, nullManifest);
|
||||
});
|
||||
}
|
||||
|
||||
function activateIFrameProvider(domain, callback) {
|
||||
let activationURL = domain + "/browser/browser/base/content/test/social/social_activate_iframe.html"
|
||||
newTab(activationURL).then(tab => {
|
||||
sendActivationEvent(tab, callback, false);
|
||||
});
|
||||
}
|
||||
|
||||
function waitForProviderLoad(origin) {
|
||||
return Promise.all([
|
||||
ensureFrameLoaded(gBrowser, origin + "/browser/browser/base/content/test/social/social_postActivation.html"),
|
||||
]);
|
||||
}
|
||||
|
||||
function getAddonItemInList(aId, aList) {
|
||||
var item = aList.firstChild;
|
||||
while (item) {
|
||||
if ("mAddon" in item && item.mAddon.id == aId) {
|
||||
aList.ensureElementIsVisible(item);
|
||||
return item;
|
||||
}
|
||||
item = item.nextSibling;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function clickAddonRemoveButton(tab, aCallback) {
|
||||
AddonManager.getAddonsByTypes(["service"], function(aAddons) {
|
||||
let addon = aAddons[0];
|
||||
|
||||
let doc = tab.linkedBrowser.contentDocument;
|
||||
let list = doc.getElementById("addon-list");
|
||||
|
||||
let item = getAddonItemInList(addon.id, list);
|
||||
let button = item._removeBtn;
|
||||
isnot(button, null, "Should have a remove button");
|
||||
ok(!button.disabled, "Button should not be disabled");
|
||||
|
||||
// uninstall happens after about:addons tab is closed, so we wait on
|
||||
// disabled
|
||||
promiseObserverNotified("social:provider-disabled").then(() => {
|
||||
is(item.getAttribute("pending"), "uninstall", "Add-on should be uninstalling");
|
||||
executeSoon(function() { aCallback(addon); });
|
||||
});
|
||||
|
||||
BrowserTestUtils.synthesizeMouseAtCenter(button, {}, tab.linkedBrowser);
|
||||
});
|
||||
}
|
||||
|
||||
function activateOneProvider(manifest, finishActivation, aCallback) {
|
||||
(async function() {
|
||||
info("activating provider " + manifest.name);
|
||||
|
||||
// Wait for the helper callback and the popup shown event in any order.
|
||||
let popupShown = BrowserTestUtils.waitForEvent(PopupNotifications.panel,
|
||||
"popupshown");
|
||||
await new Promise(resolve => activateProvider(manifest.origin, resolve));
|
||||
await popupShown;
|
||||
|
||||
info("servicesInstall-notification panel opened");
|
||||
|
||||
// Start waiting for the activation event before the click on the button.
|
||||
let providerLoaded = finishActivation ?
|
||||
waitForProviderLoad(manifest.origin) : null;
|
||||
let popupHidden = BrowserTestUtils.waitForEvent(PopupNotifications.panel,
|
||||
"popuphidden");
|
||||
|
||||
// We need to wait for PopupNotifications.jsm to place the element.
|
||||
let notification;
|
||||
await BrowserTestUtils.waitForCondition(
|
||||
() => (notification = PopupNotifications.panel.childNodes[0]));
|
||||
is(notification.id, "servicesInstall-notification");
|
||||
|
||||
if (finishActivation) {
|
||||
notification.button.click();
|
||||
} else {
|
||||
notification.closebutton.click();
|
||||
}
|
||||
|
||||
await providerLoaded;
|
||||
await popupHidden;
|
||||
|
||||
info("servicesInstall-notification panel hidden");
|
||||
|
||||
if (finishActivation) {
|
||||
checkSocialUI();
|
||||
}
|
||||
})().then(() => executeSoon(aCallback)).catch(ex => ok(false, ex));
|
||||
}
|
||||
|
||||
var gTestDomains = ["https://example.com", "https://test1.example.com", "https://test2.example.com"];
|
||||
var gProviders = [
|
||||
{
|
||||
name: "provider 1",
|
||||
origin: "https://example.com",
|
||||
shareURL: "https://example.com/browser/browser/base/content/test/social/social_share.html?provider1",
|
||||
iconURL: "chrome://branding/content/icon48.png"
|
||||
},
|
||||
{
|
||||
name: "provider 2",
|
||||
origin: "https://test1.example.com",
|
||||
shareURL: "https://test1.example.com/browser/browser/base/content/test/social/social_share.html?provider2",
|
||||
iconURL: "chrome://branding/content/icon64.png"
|
||||
},
|
||||
{
|
||||
name: "provider 3",
|
||||
origin: "https://test2.example.com",
|
||||
shareURL: "https://test2.example.com/browser/browser/base/content/test/social/social_share.html?provider2",
|
||||
iconURL: "chrome://branding/content/about-logo.png"
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
function test() {
|
||||
PopupNotifications.panel.setAttribute("animate", "false");
|
||||
registerCleanupFunction(function() {
|
||||
PopupNotifications.panel.removeAttribute("animate");
|
||||
});
|
||||
waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.ipc.processCount", 1]]}, () => {
|
||||
runSocialTests(tests, undefined, postTestCleanup);
|
||||
});
|
||||
}
|
||||
|
||||
var tests = {
|
||||
testActivationWrongOrigin(next) {
|
||||
// At this stage none of our providers exist, so we expect failure.
|
||||
Services.prefs.setBoolPref("social.remote-install.enabled", false);
|
||||
activateProvider(gTestDomains[0], function() {
|
||||
is(SocialUI.enabled, false, "SocialUI is not enabled");
|
||||
let panel = document.getElementById("servicesInstall-notification");
|
||||
ok(panel.hidden, "activation panel still hidden");
|
||||
checkSocialUI();
|
||||
Services.prefs.clearUserPref("social.remote-install.enabled");
|
||||
next();
|
||||
});
|
||||
},
|
||||
|
||||
testIFrameActivation(next) {
|
||||
activateIFrameProvider(gTestDomains[0], function() {
|
||||
is(SocialUI.enabled, false, "SocialUI is not enabled");
|
||||
let panel = document.getElementById("servicesInstall-notification");
|
||||
ok(panel.hidden, "activation panel still hidden");
|
||||
checkSocialUI();
|
||||
next();
|
||||
});
|
||||
},
|
||||
|
||||
testActivationFirstProvider(next) {
|
||||
// first up we add a manifest entry for a single provider.
|
||||
activateOneProvider(gProviders[0], false, function() {
|
||||
// we deactivated leaving no providers left, so Social is disabled.
|
||||
checkSocialUI();
|
||||
next();
|
||||
});
|
||||
},
|
||||
|
||||
testActivationMultipleProvider(next) {
|
||||
// The trick with this test is to make sure that Social.providers[1] is
|
||||
// the current provider when doing the undo - this makes sure that the
|
||||
// Social code doesn't fallback to Social.providers[0], which it will
|
||||
// do in some cases (but those cases do not include what this test does)
|
||||
// first enable the 2 providers
|
||||
SocialService.addProvider(gProviders[0], function() {
|
||||
SocialService.addProvider(gProviders[1], function() {
|
||||
checkSocialUI();
|
||||
// activate the last provider.
|
||||
activateOneProvider(gProviders[2], false, function() {
|
||||
// we deactivated - the first provider should be enabled.
|
||||
checkSocialUI();
|
||||
next();
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
testAddonManagerDoubleInstall(next) {
|
||||
// Create a new tab and load about:addons
|
||||
let addonsTab = BrowserTestUtils.addTab(gBrowser);
|
||||
gBrowser.selectedTab = addonsTab;
|
||||
BrowserOpenAddonsMgr("addons://list/service");
|
||||
gBrowser.selectedBrowser.addEventListener("load", function() {
|
||||
is(addonsTab.linkedBrowser.currentURI.spec, "about:addons", "about:addons should load into blank tab.");
|
||||
|
||||
activateOneProvider(gProviders[0], true, function() {
|
||||
info("first activation completed");
|
||||
is(gBrowser.contentDocument.location.href, gProviders[0].origin + "/browser/browser/base/content/test/social/social_postActivation.html", "postActivationURL loaded");
|
||||
BrowserTestUtils.removeTab(gBrowser.selectedTab).then(() => {
|
||||
is(gBrowser.contentDocument.location.href, gProviders[0].origin + "/browser/browser/base/content/test/social/social_activate_basic.html", "activation page selected");
|
||||
BrowserTestUtils.removeTab(gBrowser.selectedTab).then(() => {
|
||||
tabsToRemove.pop();
|
||||
// uninstall the provider
|
||||
clickAddonRemoveButton(addonsTab, function(addon) {
|
||||
checkSocialUI();
|
||||
activateOneProvider(gProviders[0], true, function() {
|
||||
info("second activation completed");
|
||||
is(gBrowser.contentDocument.location.href, gProviders[0].origin + "/browser/browser/base/content/test/social/social_postActivation.html", "postActivationURL loaded");
|
||||
BrowserTestUtils.removeTab(gBrowser.selectedTab).then(() => {
|
||||
|
||||
// after closing the addons tab, verify provider is still installed
|
||||
AddonManager.getAddonsByTypes(["service"], function(aAddons) {
|
||||
is(aAddons.length, 1, "there can be only one");
|
||||
|
||||
let doc = addonsTab.linkedBrowser.contentDocument;
|
||||
let list = doc.getElementById("addon-list");
|
||||
is(list.childNodes.length, 1, "only one addon is displayed");
|
||||
|
||||
BrowserTestUtils.removeTab(addonsTab).then(next);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}, {capture: true, once: true});
|
||||
}
|
||||
}
|
|
@ -1,263 +0,0 @@
|
|||
/* 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/. */
|
||||
|
||||
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
|
||||
"resource://gre/modules/PlacesUtils.jsm");
|
||||
|
||||
|
||||
function promiseObserverNotified(aTopic) {
|
||||
return new Promise(resolve => {
|
||||
Services.obs.addObserver(function onNotification(subject, topic, data) {
|
||||
dump("notification promised " + topic);
|
||||
Services.obs.removeObserver(onNotification, topic);
|
||||
TestUtils.executeSoon(() => resolve({subject, data}));
|
||||
}, aTopic);
|
||||
});
|
||||
}
|
||||
|
||||
// Check that a specified (string) URL hasn't been "remembered" (ie, is not
|
||||
// in history, will not appear in about:newtab or auto-complete, etc.)
|
||||
function promiseSocialUrlNotRemembered(url) {
|
||||
return new Promise(resolve => {
|
||||
let uri = Services.io.newURI(url);
|
||||
PlacesUtils.asyncHistory.isURIVisited(uri, function(aURI, aIsVisited) {
|
||||
ok(!aIsVisited, "social URL " + url + " should not be in global history");
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
var gURLsNotRemembered = [];
|
||||
|
||||
|
||||
function checkProviderPrefsEmpty(isError) {
|
||||
let MANIFEST_PREFS = Services.prefs.getBranch("social.manifest.");
|
||||
let prefs = MANIFEST_PREFS.getChildList("", []);
|
||||
let c = 0;
|
||||
for (let pref of prefs) {
|
||||
if (MANIFEST_PREFS.prefHasUserValue(pref)) {
|
||||
info("provider [" + pref + "] manifest left installed from previous test");
|
||||
c++;
|
||||
}
|
||||
}
|
||||
is(c, 0, "all provider prefs uninstalled from previous test");
|
||||
is(Social.providers.length, 0, "all providers uninstalled from previous test " + Social.providers.length);
|
||||
}
|
||||
|
||||
function defaultFinishChecks() {
|
||||
checkProviderPrefsEmpty(true);
|
||||
finish();
|
||||
}
|
||||
|
||||
function runSocialTestWithProvider(manifest, callback, finishcallback) {
|
||||
|
||||
let SocialService = Cu.import("resource:///modules/SocialService.jsm", {}).SocialService;
|
||||
|
||||
let manifests = Array.isArray(manifest) ? manifest : [manifest];
|
||||
|
||||
// Check that none of the provider's content ends up in history.
|
||||
async function finishCleanUp() {
|
||||
for (let i = 0; i < manifests.length; i++) {
|
||||
let m = manifests[i];
|
||||
for (let what of ["iconURL", "shareURL"]) {
|
||||
if (m[what]) {
|
||||
await promiseSocialUrlNotRemembered(m[what]);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < gURLsNotRemembered.length; i++) {
|
||||
await promiseSocialUrlNotRemembered(gURLsNotRemembered[i]);
|
||||
}
|
||||
gURLsNotRemembered = [];
|
||||
}
|
||||
|
||||
info("runSocialTestWithProvider: " + manifests.toSource());
|
||||
|
||||
let finishCount = 0;
|
||||
function finishIfDone(callFinish) {
|
||||
finishCount++;
|
||||
if (finishCount == manifests.length)
|
||||
finishCleanUp().then(finishcallback || defaultFinishChecks);
|
||||
}
|
||||
function removeAddedProviders(cleanup) {
|
||||
manifests.forEach(function(m) {
|
||||
// If we're "cleaning up", don't call finish when done.
|
||||
let finishCb = cleanup ? function() {} : finishIfDone;
|
||||
// Similarly, if we're cleaning up, catch exceptions from removeProvider
|
||||
let removeProvider = SocialService.disableProvider.bind(SocialService);
|
||||
if (cleanup) {
|
||||
removeProvider = function(origin, cb) {
|
||||
try {
|
||||
SocialService.disableProvider(origin, cb);
|
||||
} catch (ex) {
|
||||
// Ignore "provider doesn't exist" errors.
|
||||
if (ex.message.indexOf("SocialService.disableProvider: no provider with origin") == 0)
|
||||
return;
|
||||
info("Failed to clean up provider " + origin + ": " + ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
removeProvider(m.origin, finishCb);
|
||||
});
|
||||
}
|
||||
function finishSocialTest(cleanup) {
|
||||
removeAddedProviders(cleanup);
|
||||
}
|
||||
|
||||
let providersAdded = 0;
|
||||
|
||||
manifests.forEach(function(m) {
|
||||
SocialService.addProvider(m, function(provider) {
|
||||
|
||||
providersAdded++;
|
||||
info("runSocialTestWithProvider: provider added");
|
||||
|
||||
// If we've added all the providers we need, call the callback to start
|
||||
// the tests (and give it a callback it can call to finish them)
|
||||
if (providersAdded == manifests.length) {
|
||||
registerCleanupFunction(function() {
|
||||
finishSocialTest(true);
|
||||
});
|
||||
BrowserTestUtils.waitForCondition(() => provider.enabled,
|
||||
"providers added and enabled").then(() => {
|
||||
info("provider has been enabled");
|
||||
callback(finishSocialTest);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function runSocialTests(tests, cbPreTest, cbPostTest, cbFinish) {
|
||||
let testIter = (function*() {
|
||||
for (let name in tests) {
|
||||
if (tests.hasOwnProperty(name)) {
|
||||
yield [name, tests[name]];
|
||||
}
|
||||
}
|
||||
})();
|
||||
let providersAtStart = Social.providers.length;
|
||||
info("runSocialTests: start test run with " + providersAtStart + " providers");
|
||||
window.focus();
|
||||
|
||||
|
||||
if (cbPreTest === undefined) {
|
||||
cbPreTest = function(cb) { cb() };
|
||||
}
|
||||
if (cbPostTest === undefined) {
|
||||
cbPostTest = function(cb) { cb() };
|
||||
}
|
||||
|
||||
function runNextTest() {
|
||||
let result = testIter.next();
|
||||
if (result.done) {
|
||||
// out of items:
|
||||
(cbFinish || defaultFinishChecks)();
|
||||
is(providersAtStart, Social.providers.length,
|
||||
"runSocialTests: finish test run with " + Social.providers.length + " providers");
|
||||
return;
|
||||
}
|
||||
let [name, func] = result.value;
|
||||
// We run on a timeout to help keep the debug messages sane.
|
||||
executeSoon(function() {
|
||||
function cleanupAndRunNextTest() {
|
||||
info("sub-test " + name + " complete");
|
||||
cbPostTest(runNextTest);
|
||||
}
|
||||
cbPreTest(function() {
|
||||
info("pre-test: starting with " + Social.providers.length + " providers");
|
||||
info("sub-test " + name + " starting");
|
||||
try {
|
||||
func.call(tests, cleanupAndRunNextTest);
|
||||
} catch (ex) {
|
||||
ok(false, "sub-test " + name + " failed: " + ex.toString() + "\n" + ex.stack);
|
||||
cleanupAndRunNextTest();
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
runNextTest();
|
||||
}
|
||||
|
||||
// A fairly large hammer which checks all aspects of the SocialUI for
|
||||
// internal consistency.
|
||||
function checkSocialUI(win) {
|
||||
let SocialService = Cu.import("resource:///modules/SocialService.jsm", {}).SocialService;
|
||||
// if we have enabled providers, we should also have instances of those
|
||||
// providers
|
||||
if (SocialService.hasEnabledProviders) {
|
||||
ok(Social.providers.length > 0, "providers are enabled");
|
||||
} else {
|
||||
is(Social.providers.length, 0, "providers are not enabled");
|
||||
}
|
||||
}
|
||||
|
||||
function setManifestPref(name, manifest) {
|
||||
Services.prefs.setStringPref(name, JSON.stringify(manifest));
|
||||
}
|
||||
|
||||
function getManifestPrefname(aManifest) {
|
||||
// is same as the generated name in SocialServiceInternal.getManifestPrefname
|
||||
let originUri = Services.io.newURI(aManifest.origin);
|
||||
return "social.manifest." + originUri.hostPort.replace(".", "-");
|
||||
}
|
||||
|
||||
function ensureFrameLoaded(frame, uri) {
|
||||
return new Promise(resolve => {
|
||||
if (frame.contentDocument && frame.contentDocument.readyState == "complete" &&
|
||||
(!uri || frame.contentDocument.location.href == uri)) {
|
||||
resolve();
|
||||
} else {
|
||||
frame.addEventListener("load", function handler() {
|
||||
if (uri && frame.contentDocument.location.href != uri)
|
||||
return;
|
||||
frame.removeEventListener("load", handler, true);
|
||||
resolve()
|
||||
}, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Support for going on and offline.
|
||||
// (via browser/base/content/test/browser_bookmark_titles.js)
|
||||
var origProxyType = Services.prefs.getIntPref("network.proxy.type");
|
||||
|
||||
function toggleOfflineStatus(goOfflineState) {
|
||||
// Bug 968887 fix. when going on/offline, wait for notification before continuing
|
||||
return new Promise(resolve => {
|
||||
if (!goOfflineState) {
|
||||
Services.prefs.setIntPref("network.proxy.type", origProxyType);
|
||||
}
|
||||
if (goOfflineState != Services.io.offline) {
|
||||
info("initial offline state " + Services.io.offline);
|
||||
let expect = !Services.io.offline;
|
||||
Services.obs.addObserver(function offlineChange(subject, topic, data) {
|
||||
Services.obs.removeObserver(offlineChange, "network:offline-status-changed");
|
||||
info("offline state changed to " + Services.io.offline);
|
||||
is(expect, Services.io.offline, "network:offline-status-changed successful toggle");
|
||||
resolve();
|
||||
}, "network:offline-status-changed");
|
||||
BrowserOffline.toggleOfflineStatus();
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
if (goOfflineState) {
|
||||
Services.prefs.setIntPref("network.proxy.type", 0);
|
||||
// LOAD_FLAGS_BYPASS_CACHE isn't good enough. So clear the cache.
|
||||
Services.cache2.clear();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function goOffline() {
|
||||
// Simulate a network outage with offline mode. (Localhost is still
|
||||
// accessible in offline mode, so disable the test proxy as well.)
|
||||
return toggleOfflineStatus(true);
|
||||
}
|
||||
|
||||
function goOnline(callback) {
|
||||
return toggleOfflineStatus(false);
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<head><title>Raspberry Pi Page</title></head>
|
||||
<div class="hproduct">
|
||||
<h2 class="fn">Raspberry Pi</h2>
|
||||
<img class="photo" src="https://example.com/someimage.jpg" />
|
||||
<p class="description">The Raspberry Pi is a credit-card sized computer that plugs into your TV and a keyboard. It's a capable little PC which can be used for many of the things that your desktop PC does, like spreadsheets, word-processing and games. It also plays high-definition video. We want to see it being used by kids all over the world to learn programming.</p>
|
||||
<a class="url" href="https://example.com/">More info about the Raspberry Pi</a>
|
||||
<p class="price">29.95</p>
|
||||
<p class="review hreview"><span id="test-review" class="rating">4.5</span> out of 5</p>
|
||||
<p>Categories:
|
||||
<a rel="tag" href="https://example.com/wiki/computer" class="category">Computer</a>,
|
||||
<a rel="tag" href="https://example.com/wiki/education" class="category">Education</a>
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
Двоичные данные
browser/base/content/test/social/moz.png
Двоичные данные
browser/base/content/test/social/moz.png
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 580 B |
|
@ -1,11 +0,0 @@
|
|||
<html xmlns:og="http://ogp.me/ns#">
|
||||
<head>
|
||||
<meta property="og:url" content="chrome://browser/content/aboutDialog.xul"/>
|
||||
<meta property="og:site_name" content="Evil chrome delivering website"/>
|
||||
<meta property="og:description"
|
||||
content="A test corpus file for open graph tags passing a bad url"/>
|
||||
</head>
|
||||
<body>
|
||||
Open Graph Test Page
|
||||
</body>
|
||||
</html>
|
|
@ -1,13 +0,0 @@
|
|||
<html xmlns:og="http://ogp.me/ns#">
|
||||
<head>
|
||||
<meta property="og:title" content=">This is my title<"/>
|
||||
<meta property="og:url" content="https://www.mozilla.org"/>
|
||||
<meta property="og:image" content="https://www.mozilla.org/favicon.png"/>
|
||||
<meta property="og:site_name" content=">My simple test page<"/>
|
||||
<meta property="og:description"
|
||||
content="A test corpus file for open graph tags we care about"/>
|
||||
</head>
|
||||
<body>
|
||||
Open Graph Test Page
|
||||
</body>
|
||||
</html>
|
|
@ -1,10 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<link rel="image_src" href="http://example.com/1234/56789.jpg" id="image-src" />
|
||||
<link id="canonicalurl" rel="canonical" href="http://www.example.com/photos/56789/" />
|
||||
<link rel="shortlink" href="http://imshort/p/abcde" />
|
||||
</head>
|
||||
<body>
|
||||
link[rel='shortlink']
|
||||
</body>
|
||||
</html>
|
|
@ -1,10 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<link rel="image_src" href="http://example.com/1234/56789.jpg" id="image-src" />
|
||||
<link id="canonicalurl" rel="canonical" href="http://www.example.com/photos/56789/" />
|
||||
<link id="shorturl" rev="canonical" type="text/html" href="http://imshort/p/abcde" />
|
||||
</head>
|
||||
<body>
|
||||
link id="shorturl"
|
||||
</body>
|
||||
</html>
|
|
@ -1,25 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Test Image</title>
|
||||
|
||||
<meta name="description" content="Iron man in a tutu" />
|
||||
<meta name="title" content="Test Image" />
|
||||
|
||||
<meta name="medium" content="image" />
|
||||
<link rel="image_src" href="http://example.com/1234/56789.jpg" id="image-src" />
|
||||
<link id="canonicalurl" rel="canonical" href="http://www.example.com/photos/56789/" />
|
||||
<link id="shorturl" href="http://imshort/p/abcde" />
|
||||
|
||||
<meta property="og:title" content="TestImage" />
|
||||
<meta property="og:type" content="photos:photo" />
|
||||
<meta property="og:url" content="http://www.example.com/photos/56789/" />
|
||||
<meta property="og:site_name" content="My Photo Site" />
|
||||
<meta property="og:description" content="Iron man in a tutu" />
|
||||
<meta property="og:image" content="http://example.com/1234/56789.jpg" />
|
||||
<meta property="og:image:width" content="480" />
|
||||
<meta property="og:image:height" content="640" />
|
||||
</head>
|
||||
<body>
|
||||
link[rel='shorturl']
|
||||
</body>
|
||||
</html>
|
|
@ -1,9 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
</head>
|
||||
<body onload="document.getElementById('testclose').focus()">
|
||||
<p>This is a test social share window.</p>
|
||||
<input id="testclose"/>
|
||||
</body>
|
||||
</html>
|
|
@ -1,35 +0,0 @@
|
|||
<html>
|
||||
<!-- 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/. -->
|
||||
<head>
|
||||
<title>Activation test</title>
|
||||
</head>
|
||||
<script>
|
||||
|
||||
var data = {
|
||||
// currently required
|
||||
"name": "Demo Social Service",
|
||||
// browser_share.js serves this page from "https://example.com"
|
||||
"origin": "https://example.com",
|
||||
"iconURL": "chrome://branding/content/icon16.png",
|
||||
"icon32URL": "chrome://branding/content/favicon32.png",
|
||||
"icon64URL": "chrome://branding/content/icon64.png",
|
||||
"shareURL": "/browser/browser/base/content/test/social/share.html"
|
||||
}
|
||||
|
||||
function activate(node) {
|
||||
node.setAttribute("data-service", JSON.stringify(data));
|
||||
var event = new CustomEvent("ActivateSocialFeature");
|
||||
node.dispatchEvent(event);
|
||||
}
|
||||
|
||||
</script>
|
||||
<body>
|
||||
|
||||
nothing to see here
|
||||
|
||||
<button id="activation" onclick="activate(this, true)">Activate the share provider</button>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,41 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Activation test</title>
|
||||
</head>
|
||||
<script>
|
||||
// icons from http://findicons.com/icon/158311/firefox?id=356182 by ipapun
|
||||
var data = {
|
||||
// currently required
|
||||
"name": "Demo Social Service",
|
||||
"iconURL": "chrome://branding/content/icon16.png",
|
||||
"icon32URL": "chrome://branding/content/favicon32.png",
|
||||
"icon64URL": "chrome://branding/content/icon64.png",
|
||||
|
||||
// at least one of these must be defined
|
||||
"shareURL": "/browser/browser/base/content/test/social/social_share.html",
|
||||
"postActivationURL": "/browser/browser/base/content/test/social/social_postActivation.html",
|
||||
|
||||
// should be available for display purposes
|
||||
"description": "A short paragraph about this provider",
|
||||
"author": "Shane Caraveo, Mozilla",
|
||||
|
||||
// optional
|
||||
"version": "1.0"
|
||||
}
|
||||
|
||||
function activate(node) {
|
||||
node.setAttribute("data-service", JSON.stringify(data));
|
||||
var event = new CustomEvent("ActivateSocialFeature");
|
||||
node.dispatchEvent(event);
|
||||
}
|
||||
|
||||
</script>
|
||||
<body>
|
||||
|
||||
nothing to see here
|
||||
|
||||
<button id="activation" onclick="activate(this)">Activate The Demo Provider</button>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,41 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Activation test</title>
|
||||
</head>
|
||||
<script>
|
||||
// icons from http://findicons.com/icon/158311/firefox?id=356182 by ipapun
|
||||
var data = {
|
||||
// currently required
|
||||
"name": "Demo Social Service",
|
||||
"iconURL": "chrome://branding/content/icon16.png",
|
||||
"icon32URL": "chrome://branding/content/favicon32.png",
|
||||
"icon64URL": "chrome://branding/content/icon64.png",
|
||||
|
||||
// at least one of these must be defined
|
||||
"shareURL": "/browser/browser/base/content/test/social/social_share.html",
|
||||
"postActivationURL": "/browser/browser/base/content/test/social/social_postActivation.html",
|
||||
|
||||
// should be available for display purposes
|
||||
"description": "A short paragraph about this provider",
|
||||
"author": "Shane Caraveo, Mozilla",
|
||||
|
||||
// optional
|
||||
"version": "1.0"
|
||||
}
|
||||
|
||||
function activate(node) {
|
||||
node.setAttribute("data-service", JSON.stringify(data));
|
||||
var event = new CustomEvent("ActivateSocialFeature");
|
||||
node.dispatchEvent(event);
|
||||
}
|
||||
|
||||
</script>
|
||||
<body>
|
||||
|
||||
nothing to see here
|
||||
|
||||
<button id="activation" onclick="activate(this)">Activate The Demo Provider</button>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,11 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Activation iframe test</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<iframe src="social_activate_basic.html"/>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,12 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Post-Activation test</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
Post Activation landing page
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -164,8 +164,6 @@ var whitelist = [
|
|||
{file: "chrome://pippki/content/resetpassword.xul"},
|
||||
// Bug 1351078
|
||||
{file: "resource://gre/modules/Battery.jsm"},
|
||||
// Bug 1351070
|
||||
{file: "resource://gre/modules/ContentPrefInstance.jsm"},
|
||||
// Bug 1351079
|
||||
{file: "resource://gre/modules/ISO8601DateUtils.jsm"},
|
||||
// Bug 1337345
|
||||
|
|
|
@ -106,10 +106,6 @@
|
|||
list-style-image: var(--sidebars-icon) !important;
|
||||
}
|
||||
|
||||
:root[lwthemeicons~="--share_page-icon"] #social-share-button:-moz-lwtheme {
|
||||
list-style-image: var(--share_page-icon) !important;
|
||||
}
|
||||
|
||||
:root[lwthemeicons~="--subscribe-icon"] #feed-button:-moz-lwtheme {
|
||||
list-style-image: var(--subscribe-icon) !important;
|
||||
}
|
||||
|
@ -157,7 +153,6 @@
|
|||
:root[lwthemeicons~="--synced_tabs-icon"] #sync-button:-moz-lwtheme,
|
||||
:root[lwthemeicons~="--open_file-icon"] #open-file-button:-moz-lwtheme,
|
||||
:root[lwthemeicons~="--sidebars-icon"] #sidebar-button:-moz-lwtheme,
|
||||
:root[lwthemeicons~="--share_page-icon"] #social-share-button:-moz-lwtheme,
|
||||
:root[lwthemeicons~="--subscribe-icon"] #feed-button:-moz-lwtheme,
|
||||
:root[lwthemeicons~="--text_encoding-icon"] #characterencoding-button:-moz-lwtheme,
|
||||
:root[lwthemeicons~="--email_link-icon"] #email-link-button:-moz-lwtheme,
|
||||
|
|
|
@ -55,8 +55,6 @@ browser.jar:
|
|||
|
||||
content/browser/aboutRobots-icon.png (content/aboutRobots-icon.png)
|
||||
content/browser/aboutRobots-widget-left.png (content/aboutRobots-widget-left.png)
|
||||
content/browser/aboutSocialError.xhtml (content/aboutSocialError.xhtml)
|
||||
content/browser/aboutProviderDirectory.xhtml (content/aboutProviderDirectory.xhtml)
|
||||
content/browser/aboutTabCrashed.css (content/aboutTabCrashed.css)
|
||||
content/browser/aboutTabCrashed.js (content/aboutTabCrashed.js)
|
||||
content/browser/aboutTabCrashed.xhtml (content/aboutTabCrashed.xhtml)
|
||||
|
@ -82,7 +80,6 @@ browser.jar:
|
|||
content/browser/browser-plugins.js (content/browser-plugins.js)
|
||||
content/browser/browser-safebrowsing.js (content/browser-safebrowsing.js)
|
||||
content/browser/browser-sidebar.js (content/browser-sidebar.js)
|
||||
content/browser/browser-social.js (content/browser-social.js)
|
||||
content/browser/browser-sync.js (content/browser-sync.js)
|
||||
* content/browser/browser-tabPreviews.xml (content/browser-tabPreviews.xml)
|
||||
#ifdef CAN_DRAW_IN_TITLEBAR
|
||||
|
@ -94,7 +91,6 @@ browser.jar:
|
|||
content/browser/browser-trackingprotection.js (content/browser-trackingprotection.js)
|
||||
content/browser/tab-content.js (content/tab-content.js)
|
||||
content/browser/content.js (content/content.js)
|
||||
content/browser/social-content.js (content/social-content.js)
|
||||
content/browser/default-theme-icon.svg (content/default-theme-icon.svg)
|
||||
content/browser/defaultthemes/1.header.jpg (content/defaultthemes/1.header.jpg)
|
||||
content/browser/defaultthemes/1.icon.jpg (content/defaultthemes/1.icon.jpg)
|
||||
|
|
|
@ -31,7 +31,6 @@ BROWSER_CHROME_MANIFESTS += [
|
|||
'content/test/referrer/browser.ini',
|
||||
'content/test/sidebar/browser.ini',
|
||||
'content/test/siteIdentity/browser.ini',
|
||||
'content/test/social/browser.ini',
|
||||
'content/test/static/browser.ini',
|
||||
'content/test/sync/browser.ini',
|
||||
'content/test/tabcrashed/browser.ini',
|
||||
|
|
|
@ -49,12 +49,6 @@ static const RedirEntry kRedirMap[] = {
|
|||
nsIAboutModule::URI_CAN_LOAD_IN_CHILD |
|
||||
nsIAboutModule::ALLOW_SCRIPT |
|
||||
nsIAboutModule::HIDE_FROM_ABOUTABOUT },
|
||||
{ "socialerror", "chrome://browser/content/aboutSocialError.xhtml",
|
||||
nsIAboutModule::ALLOW_SCRIPT |
|
||||
nsIAboutModule::HIDE_FROM_ABOUTABOUT },
|
||||
{ "providerdirectory", "chrome://browser/content/aboutProviderDirectory.xhtml",
|
||||
nsIAboutModule::ALLOW_SCRIPT |
|
||||
nsIAboutModule::HIDE_FROM_ABOUTABOUT },
|
||||
{ "tabcrashed", "chrome://browser/content/aboutTabCrashed.xhtml",
|
||||
nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
|
||||
nsIAboutModule::ALLOW_SCRIPT |
|
||||
|
|
|
@ -93,8 +93,6 @@ static const mozilla::Module::ContractIDEntry kBrowserContracts[] = {
|
|||
{ NS_SESSIONSTOREUTILS_CONTRACTID, &kNS_SESSIONSTOREUTILS_CID },
|
||||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "blocked", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
|
||||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "certerror", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
|
||||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "socialerror", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
|
||||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "providerdirectory", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
|
||||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "tabcrashed", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
|
||||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "feeds", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
|
||||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "privatebrowsing", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
|
||||
|
|
|
@ -564,47 +564,6 @@ const CustomizableWidgets = [
|
|||
aNode.appendChild(obChecked);
|
||||
aNode.appendChild(obPosition);
|
||||
}
|
||||
}, {
|
||||
id: "social-share-button",
|
||||
// custom build our button so we can attach to the share command
|
||||
type: "custom",
|
||||
onBuild(aDocument) {
|
||||
let node = aDocument.createElementNS(kNSXUL, "toolbarbutton");
|
||||
node.setAttribute("id", this.id);
|
||||
node.classList.add("toolbarbutton-1");
|
||||
node.classList.add("chromeclass-toolbar-additional");
|
||||
node.setAttribute("label", CustomizableUI.getLocalizedProperty(this, "label"));
|
||||
node.setAttribute("tooltiptext", CustomizableUI.getLocalizedProperty(this, "tooltiptext"));
|
||||
node.setAttribute("removable", "true");
|
||||
node.setAttribute("observes", "Social:PageShareable");
|
||||
node.setAttribute("command", "Social:SharePage");
|
||||
|
||||
let listener = {
|
||||
onWidgetAdded: (aWidgetId) => {
|
||||
if (aWidgetId != this.id)
|
||||
return;
|
||||
|
||||
Services.obs.notifyObservers(null, "social:" + this.id + "-added");
|
||||
},
|
||||
|
||||
onWidgetRemoved: aWidgetId => {
|
||||
if (aWidgetId != this.id)
|
||||
return;
|
||||
|
||||
Services.obs.notifyObservers(null, "social:" + this.id + "-removed");
|
||||
},
|
||||
|
||||
onWidgetInstanceRemoved: (aWidgetId, aDoc) => {
|
||||
if (aWidgetId != this.id || aDoc != aDocument)
|
||||
return;
|
||||
|
||||
CustomizableUI.removeListener(listener);
|
||||
}
|
||||
};
|
||||
CustomizableUI.addListener(listener);
|
||||
|
||||
return node;
|
||||
}
|
||||
}, {
|
||||
id: "add-ons-button",
|
||||
shortcutId: "key_openAddons",
|
||||
|
|
|
@ -262,8 +262,6 @@
|
|||
onclick="PanelUI.hide();"/>
|
||||
</panelview>
|
||||
|
||||
<panelview id="PanelUI-socialapi" flex="1"/>
|
||||
|
||||
<panelview id="PanelUI-feeds" flex="1" oncommand="FeedHandler.subscribeToFeed(null, event);">
|
||||
<label value="&feedsMenu2.label;" class="panel-subview-header"/>
|
||||
</panelview>
|
||||
|
|
|
@ -670,6 +670,11 @@ this.browserAction = class extends ExtensionAPI {
|
|||
let color = browserAction.getProperty(tab, "badgeBackgroundColor");
|
||||
return Promise.resolve(color || [0xd9, 0, 0, 255]);
|
||||
},
|
||||
|
||||
openPopup: function() {
|
||||
let window = windowTracker.topWindow;
|
||||
browserAction.triggerAction(window);
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -338,6 +338,11 @@ this.pageAction = class extends ExtensionAPI {
|
|||
let popup = pageAction.getProperty(tab, "popup");
|
||||
return Promise.resolve(popup);
|
||||
},
|
||||
|
||||
openPopup: function() {
|
||||
let window = windowTracker.topWindow;
|
||||
pageAction.triggerAction(window);
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -346,6 +346,30 @@ this.sidebarAction = class extends ExtensionAPI {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens this sidebar action for the given window.
|
||||
*
|
||||
* @param {ChromeWindow} window
|
||||
*/
|
||||
open(window) {
|
||||
let {SidebarUI} = window;
|
||||
if (SidebarUI) {
|
||||
SidebarUI.show(this.id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes this sidebar action for the given window if this sidebar action is open.
|
||||
*
|
||||
* @param {ChromeWindow} window
|
||||
*/
|
||||
close(window) {
|
||||
let {SidebarUI} = window;
|
||||
if (SidebarUI.isOpen && this.id == SidebarUI.currentID) {
|
||||
SidebarUI.hide();
|
||||
}
|
||||
}
|
||||
|
||||
getAPI(context) {
|
||||
let {extension} = context;
|
||||
const sidebarAction = this;
|
||||
|
@ -406,6 +430,16 @@ this.sidebarAction = class extends ExtensionAPI {
|
|||
let panel = sidebarAction.getProperty(nativeTab, "panel");
|
||||
return Promise.resolve(panel);
|
||||
},
|
||||
|
||||
open() {
|
||||
let window = windowTracker.topWindow;
|
||||
sidebarAction.open(window);
|
||||
},
|
||||
|
||||
close() {
|
||||
let window = windowTracker.topWindow;
|
||||
sidebarAction.close(window);
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -406,24 +406,10 @@
|
|||
{
|
||||
"name": "openPopup",
|
||||
"type": "function",
|
||||
"description": "Opens the extension popup window in the active window but does not grant tab permissions.",
|
||||
"unsupported": true,
|
||||
"async": "callback",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "function",
|
||||
"name": "callback",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "popupView",
|
||||
"type": "object",
|
||||
"optional": true,
|
||||
"description": "JavaScript 'window' object for the popup window if it was succesfully opened.",
|
||||
"additionalProperties": { "type": "any" }
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
"requireUserInput": true,
|
||||
"description": "Opens the extension popup window in the active window.",
|
||||
"async": true,
|
||||
"parameters": []
|
||||
}
|
||||
],
|
||||
"events": [
|
||||
|
|
|
@ -215,6 +215,14 @@
|
|||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "openPopup",
|
||||
"type": "function",
|
||||
"requireUserInput": true,
|
||||
"description": "Opens the extension page action in the active window.",
|
||||
"async": true,
|
||||
"parameters": []
|
||||
}
|
||||
],
|
||||
"events": [
|
||||
|
|
|
@ -181,6 +181,22 @@
|
|||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "open",
|
||||
"type": "function",
|
||||
"requireUserInput": true,
|
||||
"description": "Opens the extension sidebar in the active window.",
|
||||
"async": true,
|
||||
"parameters": []
|
||||
},
|
||||
{
|
||||
"name": "close",
|
||||
"type": "function",
|
||||
"requireUserInput": true,
|
||||
"description": "Closes the extension sidebar in the active window if the sidebar belongs to the extension.",
|
||||
"async": true,
|
||||
"parameters": []
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -83,6 +83,7 @@ skip-if = true # bug 1382487
|
|||
[browser_ext_menus.js]
|
||||
[browser_ext_omnibox.js]
|
||||
skip-if = debug || asan # Bug 1354681
|
||||
[browser_ext_openPanel.js]
|
||||
[browser_ext_optionsPage_browser_style.js]
|
||||
[browser_ext_optionsPage_privileges.js]
|
||||
[browser_ext_pageAction_context.js]
|
||||
|
|
|
@ -41,7 +41,6 @@ let contextMenuItems = {
|
|||
"inspect-separator": "hidden",
|
||||
"context-inspect": "hidden",
|
||||
"context-bookmarkpage": "hidden",
|
||||
"context-sharepage": "hidden",
|
||||
};
|
||||
|
||||
add_task(async function browseraction_popup_contextmenu() {
|
||||
|
|
|
@ -0,0 +1,139 @@
|
|||
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set sts=2 sw=2 et tw=80: */
|
||||
"use strict";
|
||||
|
||||
add_task(async function test_openPopup_requires_user_interaction() {
|
||||
const {GlobalManager} = Cu.import("resource://gre/modules/Extension.jsm", {});
|
||||
|
||||
async function backgroundScript() {
|
||||
browser.tabs.onUpdated.addListener(async (tabId, changeInfo, tabInfo) => {
|
||||
if (changeInfo.status != "complete") {
|
||||
return;
|
||||
}
|
||||
await browser.pageAction.show(tabId);
|
||||
|
||||
await browser.test.assertRejects(
|
||||
browser.pageAction.openPopup(),
|
||||
"pageAction.openPopup may only be called from a user input handler",
|
||||
"The error is informative.");
|
||||
await browser.test.assertRejects(
|
||||
browser.browserAction.openPopup(),
|
||||
"browserAction.openPopup may only be called from a user input handler",
|
||||
"The error is informative.");
|
||||
await browser.test.assertRejects(
|
||||
browser.sidebarAction.open(),
|
||||
"sidebarAction.open may only be called from a user input handler",
|
||||
"The error is informative.");
|
||||
await browser.test.assertRejects(
|
||||
browser.sidebarAction.close(),
|
||||
"sidebarAction.close may only be called from a user input handler",
|
||||
"The error is informative.");
|
||||
|
||||
browser.runtime.onMessage.addListener(async msg => {
|
||||
browser.test.assertEq(msg, "from-panel", "correct message received");
|
||||
browser.test.sendMessage("panel-opened");
|
||||
});
|
||||
|
||||
browser.test.sendMessage("ready");
|
||||
});
|
||||
browser.tabs.create({url: "tab.html"});
|
||||
}
|
||||
|
||||
let extensionData = {
|
||||
background: backgroundScript,
|
||||
manifest: {
|
||||
"browser_action": {
|
||||
"default_popup": "panel.html",
|
||||
},
|
||||
"page_action": {
|
||||
"default_popup": "panel.html",
|
||||
},
|
||||
"sidebar_action": {
|
||||
"default_panel": "panel.html",
|
||||
},
|
||||
},
|
||||
|
||||
files: {
|
||||
"tab.html": `
|
||||
<!DOCTYPE html>
|
||||
<html><head><meta charset="utf-8"></head><body>
|
||||
<button id="openBrowserAction">openBrowserAction</button>
|
||||
<button id="openPageAction">openPageAction</button>
|
||||
<button id="openSidebarAction">openSidebarAction</button>
|
||||
<button id="closeSidebarAction">closeSidebarAction</button>
|
||||
<script src="tab.js"></script>
|
||||
</body></html>
|
||||
`,
|
||||
"panel.html": `
|
||||
<!DOCTYPE html>
|
||||
<html><head><meta charset="utf-8"></head><body>
|
||||
<script src="panel.js"></script>
|
||||
</body></html>
|
||||
`,
|
||||
"tab.js": function() {
|
||||
document.getElementById("openBrowserAction").addEventListener("click", () => {
|
||||
browser.browserAction.openPopup();
|
||||
}, {once: true});
|
||||
document.getElementById("openPageAction").addEventListener("click", () => {
|
||||
browser.pageAction.openPopup();
|
||||
}, {once: true});
|
||||
document.getElementById("openSidebarAction").addEventListener("click", () => {
|
||||
browser.sidebarAction.open();
|
||||
}, {once: true});
|
||||
document.getElementById("closeSidebarAction").addEventListener("click", () => {
|
||||
browser.sidebarAction.close();
|
||||
}, {once: true});
|
||||
},
|
||||
"panel.js": function() {
|
||||
browser.runtime.sendMessage("from-panel");
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
let extension = ExtensionTestUtils.loadExtension(extensionData);
|
||||
|
||||
async function click(id) {
|
||||
let open = extension.awaitMessage("panel-opened");
|
||||
await BrowserTestUtils.synthesizeMouseAtCenter(id, {}, gBrowser.selectedBrowser);
|
||||
return open;
|
||||
}
|
||||
|
||||
function testActiveTab(extension, expected) {
|
||||
let ext = GlobalManager.extensionMap.get(extension.id);
|
||||
is(ext.tabManager.hasActiveTabPermission(gBrowser.selectedTab), expected,
|
||||
"activeTab permission is correct");
|
||||
}
|
||||
|
||||
await extension.startup();
|
||||
await extension.awaitMessage("ready");
|
||||
|
||||
await click("#openBrowserAction");
|
||||
testActiveTab(extension, false);
|
||||
closeBrowserAction(extension);
|
||||
await new Promise(resolve => setTimeout(resolve, 0));
|
||||
|
||||
await click("#openPageAction");
|
||||
closePageAction(extension);
|
||||
await new Promise(resolve => setTimeout(resolve, 0));
|
||||
|
||||
await click("#openSidebarAction");
|
||||
|
||||
await BrowserTestUtils.synthesizeMouseAtCenter("#closeSidebarAction", {}, gBrowser.selectedBrowser);
|
||||
await BrowserTestUtils.waitForCondition(() => !SidebarUI.isOpen);
|
||||
|
||||
await BrowserTestUtils.removeTab(gBrowser.selectedTab);
|
||||
await extension.unload();
|
||||
|
||||
extensionData.manifest.permissions = ["activeTab"];
|
||||
extension = ExtensionTestUtils.loadExtension(extensionData);
|
||||
await extension.startup();
|
||||
await extension.awaitMessage("ready");
|
||||
|
||||
await click("#openBrowserAction");
|
||||
testActiveTab(extension, true);
|
||||
closeBrowserAction(extension);
|
||||
await new Promise(resolve => setTimeout(resolve, 0));
|
||||
|
||||
await BrowserTestUtils.removeTab(gBrowser.selectedTab);
|
||||
await extension.unload();
|
||||
});
|
|
@ -48,7 +48,6 @@ let contextMenuItems = {
|
|||
"inspect-separator": "hidden",
|
||||
"context-inspect": "hidden",
|
||||
"context-bookmarkpage": "hidden",
|
||||
"context-sharepage": "hidden",
|
||||
};
|
||||
|
||||
add_task(async function pageaction_popup_contextmenu() {
|
||||
|
|
|
@ -48,7 +48,6 @@ let contextMenuItems = {
|
|||
"inspect-separator": "hidden",
|
||||
"context-inspect": "hidden",
|
||||
"context-bookmarkpage": "hidden",
|
||||
"context-sharepage": "hidden",
|
||||
};
|
||||
|
||||
add_task(async function sidebar_contextmenu() {
|
||||
|
|
|
@ -133,7 +133,6 @@ async function runTestWithIcons(icons) {
|
|||
["synced_tabs", "#sync-button", "sync-button"],
|
||||
["open_file", "#open-file-button", "open-file-button"],
|
||||
["sidebars", "#sidebar-button", "sidebar-button"],
|
||||
["share_page", "#social-share-button", "social-share-button"],
|
||||
["subscribe", "#feed-button", "feed-button"],
|
||||
["text_encoding", "#characterencoding-button", "characterencoding-button"],
|
||||
["email_link", "#email-link-button", "email-link-button"],
|
||||
|
@ -207,7 +206,6 @@ add_task(async function test_all_icons() {
|
|||
["synced_tabs", "fox.svg"],
|
||||
["open_file", "fox.svg"],
|
||||
["sidebars", "fox.svg"],
|
||||
["share_page", "fox.svg"],
|
||||
["subscribe", "fox.svg"],
|
||||
["text_encoding", "fox.svg"],
|
||||
["email_link", "fox.svg"],
|
||||
|
@ -249,7 +247,6 @@ add_task(async function test_some_icons() {
|
|||
["synced_tabs", ""],
|
||||
["open_file", ""],
|
||||
["sidebars", ""],
|
||||
["share_page", ""],
|
||||
["subscribe", ""],
|
||||
["text_encoding", ""],
|
||||
["email_link", ""],
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
<!-- Bookmarks and history tooltip -->
|
||||
<tooltip id="bhTooltip"/>
|
||||
|
||||
<hbox id="sidebar-search-container" align="center">
|
||||
<hbox id="sidebar-search-container">
|
||||
<textbox id="search-box" flex="1" type="search"
|
||||
placeholder="&search.placeholder;"
|
||||
aria-controls="historyTree"
|
||||
|
|
|
@ -141,6 +141,8 @@ var gMainPane = {
|
|||
_ioSvc: Cc["@mozilla.org/network/io-service;1"].
|
||||
getService(Ci.nsIIOService),
|
||||
|
||||
_backoffIndex: 0,
|
||||
|
||||
/**
|
||||
* Initialization of this.
|
||||
*/
|
||||
|
@ -152,32 +154,30 @@ var gMainPane = {
|
|||
|
||||
if (AppConstants.HAVE_SHELL_SERVICE) {
|
||||
this.updateSetDefaultBrowser();
|
||||
if (AppConstants.platform == "win") {
|
||||
// In Windows 8 we launch the control panel since it's the only
|
||||
// way to get all file type association prefs. So we don't know
|
||||
// when the user will select the default. We refresh here periodically
|
||||
// in case the default changes. On other Windows OS's defaults can also
|
||||
// be set while the prefs are open.
|
||||
let win = Services.wm.getMostRecentWindow("navigator:browser");
|
||||
let win = Services.wm.getMostRecentWindow("navigator:browser");
|
||||
|
||||
let pollForDefaultBrowser = () => {
|
||||
let uri = win.gBrowser.currentURI.spec;
|
||||
// Exponential backoff mechanism will delay the polling times if user doesn't
|
||||
// trigger SetDefaultBrowser for a long time.
|
||||
let backoffTimes = [1000, 1000, 1000, 1000, 2000, 2000, 2000, 5000, 5000, 10000];
|
||||
|
||||
if ((uri == "about:preferences" || uri == "about:preferences#general") &&
|
||||
document.visibilityState == "visible") {
|
||||
this.updateSetDefaultBrowser();
|
||||
}
|
||||
let pollForDefaultBrowser = () => {
|
||||
let uri = win.gBrowser.currentURI.spec;
|
||||
|
||||
// approximately a "requestIdleInterval"
|
||||
window.setTimeout(() => {
|
||||
window.requestIdleCallback(pollForDefaultBrowser);
|
||||
}, 1000);
|
||||
};
|
||||
if ((uri == "about:preferences" || uri == "about:preferences#general") &&
|
||||
document.visibilityState == "visible") {
|
||||
this.updateSetDefaultBrowser();
|
||||
}
|
||||
|
||||
// approximately a "requestIdleInterval"
|
||||
window.setTimeout(() => {
|
||||
window.requestIdleCallback(pollForDefaultBrowser);
|
||||
}, 1000);
|
||||
}
|
||||
}, backoffTimes[this._backoffIndex + 1 < backoffTimes.length ?
|
||||
this._backoffIndex++ : backoffTimes.length - 1]);
|
||||
};
|
||||
|
||||
window.setTimeout(() => {
|
||||
window.requestIdleCallback(pollForDefaultBrowser);
|
||||
}, backoffTimes[this._backoffIndex]);
|
||||
}
|
||||
|
||||
this.initBrowserContainers();
|
||||
|
@ -861,6 +861,9 @@ var gMainPane = {
|
|||
let alwaysCheckPref = document.getElementById("browser.shell.checkDefaultBrowser");
|
||||
alwaysCheckPref.value = true;
|
||||
|
||||
// Reset exponential backoff delay time in order to do visual update in pollForDefaultBrowser.
|
||||
this._backoffIndex = 0;
|
||||
|
||||
let shellSvc = getShellService();
|
||||
if (!shellSvc)
|
||||
return;
|
||||
|
|
|
@ -128,7 +128,6 @@ divide the following different context menu situations:
|
|||
- ``canvas`` if the user opened the context menu on a canvas (that isn't a link);
|
||||
- ``media`` if the user opened the context menu on an HTML video or audio element;
|
||||
- ``input`` if the user opened the context menu on a text input element;
|
||||
- ``social`` if the user opened the context menu inside a social frame;
|
||||
- ``other`` for all other openings of the content menu;
|
||||
|
||||
Each of these objects (if they exist) then gets a "withcustom" and/or a "withoutcustom" property
|
||||
|
|
|
@ -27,6 +27,7 @@ add_task(async function test_detach_tab_marked() {
|
|||
// Check the page after the initial load
|
||||
await openPopupOn(browser, "#street-address");
|
||||
checkPopup(autoCompletePopup);
|
||||
await closePopup(browser);
|
||||
|
||||
// Detach the tab to a new window
|
||||
let newWin = gBrowser.replaceTabWithWindow(gBrowser.getTabForBrowser(browser));
|
||||
|
|
|
@ -64,8 +64,9 @@ panelmultiview[mainViewId=PanelUI-pocketView] > .panel-viewcontainer > .panel-vi
|
|||
}
|
||||
|
||||
#pocket-button-box > #pocket-animatable-box {
|
||||
/* Match the 6px margin-inline-start of .urlbar-icon plus 1px for internal padding in the animation sprite. */
|
||||
margin-inline-start: 7px;
|
||||
/* .urlbar-icon has width 28px. Each frame is 20px wide. Set margin-inline-start
|
||||
to be half the difference, 4px. */
|
||||
margin-inline-start: 4px;
|
||||
}
|
||||
|
||||
#pocket-button-box > #pocket-animatable-box > #pocket-animatable-image,
|
||||
|
|
|
@ -464,8 +464,8 @@
|
|||
@RESPATH@/components/mozProtocolHandler.manifest
|
||||
@RESPATH@/components/nsDefaultCLH.manifest
|
||||
@RESPATH@/components/nsDefaultCLH.js
|
||||
@RESPATH@/components/nsContentPrefService.manifest
|
||||
@RESPATH@/components/nsContentPrefService.js
|
||||
@RESPATH@/components/ContentPrefService2.manifest
|
||||
@RESPATH@/components/ContentPrefService2.js
|
||||
@RESPATH@/components/nsContentDispatchChooser.manifest
|
||||
@RESPATH@/components/nsContentDispatchChooser.js
|
||||
@RESPATH@/components/nsHandlerService-json.manifest
|
||||
|
|
|
@ -161,22 +161,7 @@ These should match what Safari and other Apple applications use on OS X Lion. --
|
|||
<!ENTITY bookmarkThisPageCmd.label "Bookmark This Page">
|
||||
<!ENTITY editThisBookmarkCmd.label "Edit This Bookmark">
|
||||
<!ENTITY bookmarkThisPageCmd.commandkey "d">
|
||||
<!-- LOCALIZATION NOTE (findShareServices.label):
|
||||
- Use the unicode ellipsis char, \u2026,
|
||||
- or use "..." if \u2026 doesn't suit traditions in your locale. -->
|
||||
<!ENTITY findShareServices.label "Find more Share services…">
|
||||
<!ENTITY sharePageCmd.label "Share This Page">
|
||||
<!ENTITY sharePageCmd.commandkey "S">
|
||||
<!ENTITY sharePageCmd.accesskey "s">
|
||||
<!-- LOCALIZATION NOTE (shareLink.accesskey): must be different than the following share access keys -->
|
||||
<!ENTITY shareLink.label "Share This Link">
|
||||
<!ENTITY shareLink.accesskey "h">
|
||||
<!ENTITY shareImage.label "Share This Image">
|
||||
<!ENTITY shareImage.accesskey "r">
|
||||
<!ENTITY shareSelect.label "Share Selection">
|
||||
<!ENTITY shareSelect.accesskey "r">
|
||||
<!ENTITY shareVideo.label "Share This Video">
|
||||
<!ENTITY shareVideo.accesskey "r">
|
||||
|
||||
<!ENTITY feedsMenu2.label "Subscribe to This Page">
|
||||
<!ENTITY subscribeToPageMenupopup.label "Subscribe to This Page">
|
||||
<!ENTITY subscribeToPageMenuitem.label "Subscribe to This Page…">
|
||||
|
@ -841,14 +826,6 @@ you can use these alternative items. Otherwise, their values should be empty. -
|
|||
<!ENTITY syncReAuthItem.accesskey "R">
|
||||
<!ENTITY syncToolbarButton.label "Sync">
|
||||
|
||||
<!ENTITY social.addons.label "Manage Services…">
|
||||
|
||||
<!ENTITY social.directory.label "Activations Directory">
|
||||
<!ENTITY social.directory.text "You can activate Share services from the directory.">
|
||||
<!ENTITY social.directory.button "Take me there!">
|
||||
<!ENTITY social.directory.introText "Click on a service to add it to &brandShortName;.">
|
||||
<!ENTITY social.directory.viewmore.text "View More">
|
||||
|
||||
<!ENTITY customizeMode.menuAndToolbars.header2 "Additional Tools and Features">
|
||||
<!ENTITY customizeMode.menuAndToolbars.empty "Want more tools?">
|
||||
<!ENTITY customizeMode.menuAndToolbars.emptyLink "Choose from thousands of add-ons">
|
||||
|
|
|
@ -596,33 +596,10 @@ processHang.button_debug.accessKey = D
|
|||
# LOCALIZATION NOTE (fullscreenButton.tooltip): %S is the keyboard shortcut for full screen
|
||||
fullscreenButton.tooltip=Display the window in full screen (%S)
|
||||
|
||||
service.toolbarbutton.label=Services
|
||||
service.toolbarbutton.tooltiptext=Services
|
||||
|
||||
# LOCALIZATION NOTE (social.install.description): %1$S is the hostname of the social provider, %2$S is brandShortName (e.g. Firefox)
|
||||
service.install.description=Would you like to enable services from %1$S to display in your %2$S toolbar and sidebar?
|
||||
service.install.ok.label=Enable Services
|
||||
service.install.ok.accesskey=E
|
||||
|
||||
# These are visible when opening the popup inside the bookmarks sidebar
|
||||
sidebar.moveToLeft=Move Sidebar to Left
|
||||
sidebar.moveToRight=Move Sidebar to Right
|
||||
|
||||
# LOCALIZATION NOTE (social.markpageMenu.label): %S is the name of the social provider
|
||||
social.markpageMenu.label=Save Page to %S
|
||||
# LOCALIZATION NOTE (social.marklinkMenu.label): %S is the name of the social provider
|
||||
social.marklinkMenu.label=Save Link to %S
|
||||
|
||||
# LOCALIZATION NOTE (social.error.message): %1$S is brandShortName (e.g. Firefox), %2$S is the name of the social provider
|
||||
social.error.message=%1$S is unable to connect with %2$S right now.
|
||||
social.error.tryAgain.label=Try Again
|
||||
social.error.tryAgain.accesskey=T
|
||||
social.error.closeSidebar.label=Close This Sidebar
|
||||
social.error.closeSidebar.accesskey=C
|
||||
|
||||
# LOCALIZATION NOTE: %1$S is the label for the toolbar button, %2$S is the associated badge numbering that the social provider may provide.
|
||||
social.aria.toolbarButtonBadgeText=%1$S (%2$S)
|
||||
|
||||
# LOCALIZATION NOTE (getUserMedia.shareCamera2.message,
|
||||
# getUserMedia.shareMicrophone2.message,
|
||||
# getUserMedia.shareScreen3.message,
|
||||
|
|
|
@ -95,9 +95,6 @@ quit-button.tooltiptext.linux2 = Quit %1$S (%2$S)
|
|||
# %2$S is the keyboard shortcut
|
||||
quit-button.tooltiptext.mac = Quit %1$S (%2$S)
|
||||
|
||||
social-share-button.label = Share This Page
|
||||
social-share-button.tooltiptext = Share this page
|
||||
|
||||
panic-button.label = Forget
|
||||
panic-button.tooltiptext = Forget about some browsing history
|
||||
|
||||
|
|
|
@ -690,7 +690,7 @@ this.BrowserUITelemetry = {
|
|||
"spell-undo-add-to-dictionary", "openlinkincurrent", "openlinkintab",
|
||||
"openlink",
|
||||
// "openlinkprivate" intentionally omitted for privacy reasons. See bug 1176391.
|
||||
"bookmarklink", "sharelink", "savelink",
|
||||
"bookmarklink", "savelink",
|
||||
"marklinkMenu", "copyemail", "copylink", "media-play", "media-pause",
|
||||
"media-mute", "media-unmute", "media-playbackrate",
|
||||
"media-playbackrate-050x", "media-playbackrate-100x",
|
||||
|
@ -698,12 +698,12 @@ this.BrowserUITelemetry = {
|
|||
"media-showcontrols", "media-hidecontrols",
|
||||
"video-fullscreen", "leave-dom-fullscreen",
|
||||
"reloadimage", "viewimage", "viewvideo", "copyimage-contents", "copyimage",
|
||||
"copyvideourl", "copyaudiourl", "saveimage", "shareimage", "sendimage",
|
||||
"copyvideourl", "copyaudiourl", "saveimage", "sendimage",
|
||||
"setDesktopBackground", "viewimageinfo", "viewimagedesc", "savevideo",
|
||||
"sharevideo", "saveaudio", "video-saveimage", "sendvideo", "sendaudio",
|
||||
"ctp-play", "ctp-hide", "sharepage", "savepage", "pocket", "markpageMenu",
|
||||
"saveaudio", "video-saveimage", "sendvideo", "sendaudio",
|
||||
"ctp-play", "ctp-hide", "savepage", "pocket", "markpageMenu",
|
||||
"viewbgimage", "undo", "cut", "copy", "paste", "delete", "selectall",
|
||||
"keywordfield", "searchselect", "shareselect", "frame", "showonlythisframe",
|
||||
"keywordfield", "searchselect", "frame", "showonlythisframe",
|
||||
"openframeintab", "openframe", "reloadframe", "bookmarkframe", "saveframe",
|
||||
"printframe", "viewframesource", "viewframeinfo",
|
||||
"viewpartialsource-selection", "viewpartialsource-mathml",
|
||||
|
|
|
@ -1,272 +0,0 @@
|
|||
/* 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";
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["Social", "OpenGraphBuilder",
|
||||
"DynamicResizeWatcher", "sizeSocialPanelToContent"];
|
||||
|
||||
const Ci = Components.interfaces;
|
||||
const Cc = Components.classes;
|
||||
const Cu = Components.utils;
|
||||
|
||||
// The minimum sizes for the auto-resize panel code, minimum size necessary to
|
||||
// properly show the error page in the panel.
|
||||
const PANEL_MIN_HEIGHT = 190;
|
||||
const PANEL_MIN_WIDTH = 330;
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "CustomizableUI",
|
||||
"resource:///modules/CustomizableUI.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "SocialService",
|
||||
"resource:///modules/SocialService.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "PageMetadata",
|
||||
"resource://gre/modules/PageMetadata.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
|
||||
"resource://gre/modules/PlacesUtils.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "PromiseUtils",
|
||||
"resource://gre/modules/PromiseUtils.jsm");
|
||||
|
||||
|
||||
this.Social = {
|
||||
initialized: false,
|
||||
lastEventReceived: 0,
|
||||
providers: [],
|
||||
_disabledForSafeMode: false,
|
||||
|
||||
init: function Social_init() {
|
||||
this._disabledForSafeMode = Services.appinfo.inSafeMode && this.enabled;
|
||||
let deferred = PromiseUtils.defer();
|
||||
|
||||
if (this.initialized) {
|
||||
deferred.resolve(true);
|
||||
return deferred.promise;
|
||||
}
|
||||
this.initialized = true;
|
||||
// if SocialService.hasEnabledProviders, retreive the providers so the
|
||||
// front-end can generate UI
|
||||
if (SocialService.hasEnabledProviders) {
|
||||
// Retrieve the current set of providers, and set the current provider.
|
||||
SocialService.getOrderedProviderList(function(providers) {
|
||||
Social._updateProviderCache(providers);
|
||||
Social._updateEnabledState(SocialService.enabled);
|
||||
deferred.resolve(false);
|
||||
});
|
||||
} else {
|
||||
deferred.resolve(false);
|
||||
}
|
||||
|
||||
// Register an observer for changes to the provider list
|
||||
SocialService.registerProviderListener(function providerListener(topic, origin, providers) {
|
||||
// An engine change caused by adding/removing a provider should notify.
|
||||
// any providers we receive are enabled in the AddonsManager
|
||||
if (topic == "provider-installed" || topic == "provider-uninstalled") {
|
||||
// installed/uninstalled do not send the providers param
|
||||
Services.obs.notifyObservers(null, "social:" + topic, origin);
|
||||
return;
|
||||
}
|
||||
if (topic == "provider-enabled") {
|
||||
Social._updateProviderCache(providers);
|
||||
Social._updateEnabledState(true);
|
||||
Services.obs.notifyObservers(null, "social:" + topic, origin);
|
||||
return;
|
||||
}
|
||||
if (topic == "provider-disabled") {
|
||||
// a provider was removed from the list of providers, update states
|
||||
Social._updateProviderCache(providers);
|
||||
Social._updateEnabledState(providers.length > 0);
|
||||
Services.obs.notifyObservers(null, "social:" + topic, origin);
|
||||
return;
|
||||
}
|
||||
if (topic == "provider-update") {
|
||||
// a provider has self-updated its manifest, we need to update our cache
|
||||
// and reload the provider.
|
||||
Social._updateProviderCache(providers);
|
||||
let provider = Social._getProviderFromOrigin(origin);
|
||||
provider.reload();
|
||||
}
|
||||
});
|
||||
return deferred.promise;
|
||||
},
|
||||
|
||||
_updateEnabledState(enable) {
|
||||
for (let p of Social.providers) {
|
||||
p.enabled = enable;
|
||||
}
|
||||
},
|
||||
|
||||
// Called to update our cache of providers and set the current provider
|
||||
_updateProviderCache(providers) {
|
||||
this.providers = providers;
|
||||
Services.obs.notifyObservers(null, "social:providers-changed");
|
||||
},
|
||||
|
||||
get enabled() {
|
||||
return !this._disabledForSafeMode && this.providers.length > 0;
|
||||
},
|
||||
|
||||
_getProviderFromOrigin(origin) {
|
||||
for (let p of this.providers) {
|
||||
if (p.origin == origin) {
|
||||
return p;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
getManifestByOrigin(origin) {
|
||||
return SocialService.getManifestByOrigin(origin);
|
||||
},
|
||||
|
||||
installProvider(data, installCallback, options = {}) {
|
||||
SocialService.installProvider(data, installCallback, options);
|
||||
},
|
||||
|
||||
uninstallProvider(origin, aCallback) {
|
||||
SocialService.uninstallProvider(origin, aCallback);
|
||||
},
|
||||
|
||||
// Activation functionality
|
||||
activateFromOrigin(origin, callback) {
|
||||
// It's OK if the provider has already been activated - we still get called
|
||||
// back with it.
|
||||
SocialService.enableProvider(origin, callback);
|
||||
}
|
||||
};
|
||||
|
||||
function sizeSocialPanelToContent(panel, iframe, requestedSize) {
|
||||
let doc = iframe.contentDocument;
|
||||
if (!doc || !doc.body) {
|
||||
return;
|
||||
}
|
||||
// We need an element to use for sizing our panel. See if the body defines
|
||||
// an id for that element, otherwise use the body itself.
|
||||
let body = doc.body;
|
||||
let docEl = doc.documentElement;
|
||||
let bodyId = body.getAttribute("contentid");
|
||||
if (bodyId) {
|
||||
body = doc.getElementById(bodyId) || doc.body;
|
||||
}
|
||||
// offsetHeight/Width don't include margins, so account for that.
|
||||
let cs = doc.defaultView.getComputedStyle(body);
|
||||
let width = Math.max(PANEL_MIN_WIDTH, docEl.offsetWidth);
|
||||
let height = Math.max(PANEL_MIN_HEIGHT, docEl.offsetHeight);
|
||||
// if the panel is preloaded prior to being shown, cs will be null. in that
|
||||
// case use the minimum size for the panel until it is shown.
|
||||
if (cs) {
|
||||
let computedHeight = parseInt(cs.marginTop) + body.offsetHeight + parseInt(cs.marginBottom);
|
||||
height = Math.max(computedHeight, height);
|
||||
let computedWidth = parseInt(cs.marginLeft) + body.offsetWidth + parseInt(cs.marginRight);
|
||||
width = Math.max(computedWidth, width);
|
||||
}
|
||||
|
||||
// if our scrollHeight is still larger than the iframe, the css calculations
|
||||
// above did not work for this site, increase the height. This can happen if
|
||||
// the site increases its height for additional UI.
|
||||
if (docEl.scrollHeight > iframe.boxObject.height)
|
||||
height = docEl.scrollHeight;
|
||||
|
||||
// if a size was defined in the manifest use it as a minimum
|
||||
if (requestedSize) {
|
||||
if (requestedSize.height)
|
||||
height = Math.max(height, requestedSize.height);
|
||||
if (requestedSize.width)
|
||||
width = Math.max(width, requestedSize.width);
|
||||
}
|
||||
|
||||
// add the extra space used by the panel (toolbar, borders, etc) if the iframe
|
||||
// has been loaded
|
||||
if (iframe.boxObject.width && iframe.boxObject.height) {
|
||||
// add extra space the panel needs if any
|
||||
width += panel.boxObject.width - iframe.boxObject.width;
|
||||
height += panel.boxObject.height - iframe.boxObject.height;
|
||||
}
|
||||
|
||||
// using panel.sizeTo will ignore css transitions, set size via style
|
||||
if (Math.abs(panel.boxObject.width - width) >= 2)
|
||||
panel.style.width = width + "px";
|
||||
if (Math.abs(panel.boxObject.height - height) >= 2)
|
||||
panel.style.height = height + "px";
|
||||
}
|
||||
|
||||
function DynamicResizeWatcher() {
|
||||
this._mutationObserver = null;
|
||||
}
|
||||
|
||||
DynamicResizeWatcher.prototype = {
|
||||
start: function DynamicResizeWatcher_start(panel, iframe, requestedSize) {
|
||||
this.stop(); // just in case...
|
||||
let doc = iframe.contentDocument;
|
||||
this._mutationObserver = new iframe.contentWindow.MutationObserver((mutations) => {
|
||||
sizeSocialPanelToContent(panel, iframe, requestedSize);
|
||||
});
|
||||
// Observe anything that causes the size to change.
|
||||
let config = {attributes: true, characterData: true, childList: true, subtree: true};
|
||||
this._mutationObserver.observe(doc, config);
|
||||
// and since this may be setup after the load event has fired we do an
|
||||
// initial resize now.
|
||||
sizeSocialPanelToContent(panel, iframe, requestedSize);
|
||||
},
|
||||
stop: function DynamicResizeWatcher_stop() {
|
||||
if (this._mutationObserver) {
|
||||
try {
|
||||
this._mutationObserver.disconnect();
|
||||
} catch (ex) {
|
||||
// may get "TypeError: can't access dead object" which seems strange,
|
||||
// but doesn't seem to indicate a real problem, so ignore it...
|
||||
}
|
||||
this._mutationObserver = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
this.OpenGraphBuilder = {
|
||||
generateEndpointURL(URLTemplate, pageData) {
|
||||
// support for existing oexchange style endpoints by supporting their
|
||||
// querystring arguments. parse the query string template and do
|
||||
// replacements where necessary the query names may be different than ours,
|
||||
// so we could see u=%{url} or url=%{url}
|
||||
let [endpointURL, queryString] = URLTemplate.split("?");
|
||||
let query = {};
|
||||
if (queryString) {
|
||||
queryString.split("&").forEach(function(val) {
|
||||
let [name, value] = val.split("=");
|
||||
let p = /%\{(.+)\}/.exec(value);
|
||||
if (!p) {
|
||||
// preserve non-template query vars
|
||||
query[name] = value;
|
||||
} else if (pageData[p[1]]) {
|
||||
if (p[1] == "previews")
|
||||
query[name] = pageData[p[1]][0];
|
||||
else
|
||||
query[name] = pageData[p[1]];
|
||||
} else if (p[1] == "body") {
|
||||
// build a body for emailers
|
||||
let body = "";
|
||||
if (pageData.title)
|
||||
body += pageData.title + "\n\n";
|
||||
if (pageData.description)
|
||||
body += pageData.description + "\n\n";
|
||||
if (pageData.text)
|
||||
body += pageData.text + "\n\n";
|
||||
body += pageData.url;
|
||||
query.body = body;
|
||||
}
|
||||
});
|
||||
// if the url template doesn't have title and no text was provided, add the title as the text.
|
||||
if (!query.text && !query.title && pageData.title) {
|
||||
query.text = pageData.title;
|
||||
}
|
||||
}
|
||||
var str = [];
|
||||
for (let p in query)
|
||||
str.push(p + "=" + encodeURIComponent(query[p]));
|
||||
if (str.length)
|
||||
endpointURL = endpointURL + "?" + str.join("&");
|
||||
return endpointURL;
|
||||
},
|
||||
};
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -94,9 +94,6 @@ with Files("Sanitizer.jsm"):
|
|||
with Files("SitePermissions.jsm"):
|
||||
BUG_COMPONENT = ("Firefox", "Site Identity and Permission Panels")
|
||||
|
||||
with Files("Social*"):
|
||||
BUG_COMPONENT = ("Firefox", "SocialAPI")
|
||||
|
||||
with Files("TransientPrefs.jsm"):
|
||||
BUG_COMPONENT = ("Firefox", "Preferences")
|
||||
|
||||
|
@ -123,10 +120,7 @@ with Files("ZoomUI.jsm"):
|
|||
|
||||
|
||||
BROWSER_CHROME_MANIFESTS += ['test/browser/browser.ini']
|
||||
XPCSHELL_TESTS_MANIFESTS += [
|
||||
'test/unit/social/xpcshell.ini',
|
||||
'test/unit/xpcshell.ini',
|
||||
]
|
||||
XPCSHELL_TESTS_MANIFESTS += ['test/unit/xpcshell.ini']
|
||||
|
||||
EXTRA_JS_MODULES += [
|
||||
'AboutHome.jsm',
|
||||
|
@ -158,8 +152,6 @@ EXTRA_JS_MODULES += [
|
|||
'RemotePrompt.jsm',
|
||||
'Sanitizer.jsm',
|
||||
'SitePermissions.jsm',
|
||||
'Social.jsm',
|
||||
'SocialService.jsm',
|
||||
'TransientPrefs.jsm',
|
||||
'UpdateTopLevelContentWindowIDHelper.jsm',
|
||||
'webrtcUI.jsm',
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist">
|
||||
<emItems>
|
||||
<emItem blockID="s1" id="bad.com@services.mozilla.org"></emItem>
|
||||
</emItems>
|
||||
</blocklist>
|
|
@ -1,202 +0,0 @@
|
|||
/* 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/. */
|
||||
|
||||
var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
var Social, SocialService;
|
||||
|
||||
var manifests = [
|
||||
{
|
||||
name: "provider 1",
|
||||
origin: "https://example1.com",
|
||||
sidebarURL: "https://example1.com/sidebar/",
|
||||
},
|
||||
{
|
||||
name: "provider 2",
|
||||
origin: "https://example2.com",
|
||||
sidebarURL: "https://example1.com/sidebar/",
|
||||
}
|
||||
];
|
||||
|
||||
const MANIFEST_PREFS = Services.prefs.getBranch("social.manifest.");
|
||||
|
||||
// SocialProvider class relies on blocklisting being enabled. To enable
|
||||
// blocklisting, we have to setup an app and initialize the blocklist (see
|
||||
// initApp below).
|
||||
const gProfD = do_get_profile();
|
||||
|
||||
function createAppInfo(ID, name, version, platformVersion = "1.0") {
|
||||
let tmp = {};
|
||||
Cu.import("resource://testing-common/AppInfo.jsm", tmp);
|
||||
tmp.updateAppInfo({
|
||||
ID, name, version, platformVersion,
|
||||
crashReporter: true,
|
||||
});
|
||||
}
|
||||
|
||||
function initApp() {
|
||||
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9");
|
||||
// prepare a blocklist file for the blocklist service
|
||||
var blocklistFile = gProfD.clone();
|
||||
blocklistFile.append("blocklist.xml");
|
||||
if (blocklistFile.exists())
|
||||
blocklistFile.remove(false);
|
||||
var source = do_get_file("blocklist.xml");
|
||||
source.copyTo(gProfD, "blocklist.xml");
|
||||
blocklistFile.lastModifiedTime = Date.now();
|
||||
|
||||
|
||||
let internalManager = Cc["@mozilla.org/addons/integration;1"].
|
||||
getService(Ci.nsIObserver).
|
||||
QueryInterface(Ci.nsITimerCallback);
|
||||
|
||||
internalManager.observe(null, "addons-startup", null);
|
||||
}
|
||||
|
||||
function setManifestPref(manifest) {
|
||||
Services.prefs.setStringPref("social.manifest." + manifest.origin,
|
||||
JSON.stringify(manifest));
|
||||
}
|
||||
|
||||
function do_wait_observer(obsTopic, cb) {
|
||||
function observer(subject, topic, data) {
|
||||
Services.obs.removeObserver(observer, topic);
|
||||
cb();
|
||||
}
|
||||
Services.obs.addObserver(observer, obsTopic);
|
||||
}
|
||||
|
||||
function do_add_providers(cb) {
|
||||
// run only after social is already initialized
|
||||
SocialService.addProvider(manifests[0], function() {
|
||||
do_wait_observer("social:providers-changed", function() {
|
||||
do_check_eq(Social.providers.length, 2, "2 providers installed");
|
||||
do_execute_soon(cb);
|
||||
});
|
||||
SocialService.addProvider(manifests[1]);
|
||||
});
|
||||
}
|
||||
|
||||
function do_initialize_social(enabledOnStartup, cb) {
|
||||
initApp();
|
||||
|
||||
if (enabledOnStartup) {
|
||||
// set prefs before initializing social
|
||||
manifests.forEach(function(manifest) {
|
||||
setManifestPref(manifest);
|
||||
});
|
||||
// Set both providers active and flag the first one as "current"
|
||||
let active = {};
|
||||
for (let m of manifests)
|
||||
active[m.origin] = 1;
|
||||
Services.prefs.setStringPref("social.activeProviders",
|
||||
JSON.stringify(active));
|
||||
|
||||
do_register_cleanup(function() {
|
||||
manifests.forEach(function(manifest) {
|
||||
Services.prefs.clearUserPref("social.manifest." + manifest.origin);
|
||||
});
|
||||
Services.prefs.clearUserPref("social.activeProviders");
|
||||
});
|
||||
|
||||
// expecting 2 providers installed
|
||||
do_wait_observer("social:providers-changed", function() {
|
||||
do_check_eq(Social.providers.length, 2, "2 providers installed");
|
||||
do_execute_soon(cb);
|
||||
});
|
||||
}
|
||||
|
||||
// import and initialize everything
|
||||
SocialService = Cu.import("resource:///modules/SocialService.jsm", {}).SocialService;
|
||||
do_check_eq(enabledOnStartup, SocialService.hasEnabledProviders, "Service has enabled providers");
|
||||
Social = Cu.import("resource:///modules/Social.jsm", {}).Social;
|
||||
do_check_false(Social.initialized, "Social is not initialized");
|
||||
Social.init();
|
||||
do_check_true(Social.initialized, "Social is initialized");
|
||||
if (!enabledOnStartup)
|
||||
do_execute_soon(cb);
|
||||
}
|
||||
|
||||
function AsyncRunner() {
|
||||
do_test_pending();
|
||||
do_register_cleanup(() => this.destroy());
|
||||
|
||||
this._callbacks = {
|
||||
done: do_test_finished,
|
||||
error(err) {
|
||||
// xpcshell test functions like do_check_eq throw NS_ERROR_ABORT on
|
||||
// failure. Ignore those so they aren't rethrown here.
|
||||
if (err !== Cr.NS_ERROR_ABORT) {
|
||||
if (err.stack) {
|
||||
err = err + " - See following stack:\n" + err.stack +
|
||||
"\nUseless do_throw stack";
|
||||
}
|
||||
do_throw(err);
|
||||
}
|
||||
},
|
||||
consoleError(scriptErr) {
|
||||
// Try to ensure the error is related to the test.
|
||||
let filename = scriptErr.sourceName || scriptErr.toString() || "";
|
||||
if (filename.indexOf("/toolkit/components/social/") >= 0)
|
||||
do_throw(scriptErr);
|
||||
},
|
||||
};
|
||||
this._iteratorQueue = [];
|
||||
|
||||
// This catches errors reported to the console, e.g., via Cu.reportError, but
|
||||
// not on the runner's stack.
|
||||
Cc["@mozilla.org/consoleservice;1"].
|
||||
getService(Ci.nsIConsoleService).
|
||||
registerListener(this);
|
||||
}
|
||||
|
||||
AsyncRunner.prototype = {
|
||||
|
||||
appendIterator: function appendIterator(iter) {
|
||||
this._iteratorQueue.push(iter);
|
||||
},
|
||||
|
||||
next: function next(arg) {
|
||||
if (!this._iteratorQueue.length) {
|
||||
this.destroy();
|
||||
this._callbacks.done();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
var { done, value: val } = this._iteratorQueue[0].next(arg);
|
||||
if (done) {
|
||||
this._iteratorQueue.shift();
|
||||
this.next();
|
||||
return;
|
||||
}
|
||||
} catch (err) {
|
||||
this._callbacks.error(err);
|
||||
}
|
||||
|
||||
// val is an iterator => prepend it to the queue and start on it
|
||||
// val is otherwise truthy => call next
|
||||
if (val) {
|
||||
if (typeof(val) != "boolean")
|
||||
this._iteratorQueue.unshift(val);
|
||||
this.next();
|
||||
}
|
||||
},
|
||||
|
||||
destroy: function destroy() {
|
||||
Cc["@mozilla.org/consoleservice;1"].
|
||||
getService(Ci.nsIConsoleService).
|
||||
unregisterListener(this);
|
||||
this.destroy = function alreadyDestroyed() {};
|
||||
},
|
||||
|
||||
observe: function observe(msg) {
|
||||
if (msg instanceof Ci.nsIScriptError &&
|
||||
!(msg.flags & Ci.nsIScriptError.warningFlag)) {
|
||||
this._callbacks.consoleError(msg);
|
||||
}
|
||||
},
|
||||
};
|
|
@ -1,166 +0,0 @@
|
|||
/* 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/. */
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "PlacesTestUtils",
|
||||
"resource://testing-common/PlacesTestUtils.jsm");
|
||||
|
||||
function run_test() {
|
||||
initApp();
|
||||
|
||||
// NOTE: none of the manifests here can have a workerURL set, or we attempt
|
||||
// to create a FrameWorker and that fails under xpcshell...
|
||||
let manifests = [
|
||||
{ // normal provider
|
||||
name: "provider 1",
|
||||
origin: "https://example1.com",
|
||||
shareURL: "https://example1.com/share/",
|
||||
},
|
||||
{ // provider without workerURL
|
||||
name: "provider 2",
|
||||
origin: "https://example2.com",
|
||||
shareURL: "https://example2.com/share/",
|
||||
}
|
||||
];
|
||||
|
||||
Cu.import("resource:///modules/SocialService.jsm");
|
||||
|
||||
let runner = new AsyncRunner();
|
||||
let next = runner.next.bind(runner);
|
||||
runner.appendIterator(testAddProviders(manifests, next));
|
||||
runner.appendIterator(testGetProvider(manifests, next));
|
||||
runner.appendIterator(testGetProviderList(manifests, next));
|
||||
runner.appendIterator(testAddRemoveProvider(manifests, next));
|
||||
runner.appendIterator(testIsSameOrigin(manifests, next));
|
||||
runner.appendIterator(testResolveUri(manifests, next));
|
||||
runner.appendIterator(testOrderedProviders(manifests, next));
|
||||
runner.appendIterator(testRemoveProviders(manifests, next));
|
||||
runner.next();
|
||||
}
|
||||
|
||||
function* testAddProviders(manifests, next) {
|
||||
do_check_false(SocialService.enabled);
|
||||
let provider = yield SocialService.addProvider(manifests[0], next);
|
||||
do_check_true(SocialService.enabled);
|
||||
do_check_false(provider.enabled);
|
||||
provider = yield SocialService.addProvider(manifests[1], next);
|
||||
do_check_false(provider.enabled);
|
||||
}
|
||||
|
||||
function* testRemoveProviders(manifests, next) {
|
||||
do_check_true(SocialService.enabled);
|
||||
yield SocialService.disableProvider(manifests[0].origin, next);
|
||||
yield SocialService.disableProvider(manifests[1].origin, next);
|
||||
do_check_false(SocialService.enabled);
|
||||
}
|
||||
|
||||
function* testGetProvider(manifests, next) {
|
||||
for (let i = 0; i < manifests.length; i++) {
|
||||
let manifest = manifests[i];
|
||||
let provider = yield SocialService.getProvider(manifest.origin, next);
|
||||
do_check_neq(provider, null);
|
||||
do_check_eq(provider.name, manifest.name);
|
||||
do_check_eq(provider.workerURL, manifest.workerURL);
|
||||
do_check_eq(provider.origin, manifest.origin);
|
||||
}
|
||||
do_check_eq((yield SocialService.getProvider("bogus", next)), null);
|
||||
}
|
||||
|
||||
function* testGetProviderList(manifests, next) {
|
||||
let providers = yield SocialService.getProviderList(next);
|
||||
do_check_true(providers.length >= manifests.length);
|
||||
for (let i = 0; i < manifests.length; i++) {
|
||||
let providerIdx = providers.map(p => p.origin).indexOf(manifests[i].origin);
|
||||
let provider = providers[providerIdx];
|
||||
do_check_true(!!provider);
|
||||
do_check_false(provider.enabled);
|
||||
do_check_eq(provider.workerURL, manifests[i].workerURL);
|
||||
do_check_eq(provider.name, manifests[i].name);
|
||||
}
|
||||
}
|
||||
|
||||
function* testAddRemoveProvider(manifests, next) {
|
||||
var threw;
|
||||
try {
|
||||
// Adding a provider whose origin already exists should fail
|
||||
SocialService.addProvider(manifests[0]);
|
||||
} catch (ex) {
|
||||
threw = ex;
|
||||
}
|
||||
do_check_neq(threw.toString().indexOf("SocialService.addProvider: provider with this origin already exists"), -1);
|
||||
|
||||
let originalProviders = yield SocialService.getProviderList(next);
|
||||
|
||||
// Check that provider installation succeeds
|
||||
let newProvider = yield SocialService.addProvider({
|
||||
name: "foo",
|
||||
origin: "http://example3.com"
|
||||
}, next);
|
||||
let retrievedNewProvider = yield SocialService.getProvider(newProvider.origin, next);
|
||||
do_check_eq(newProvider, retrievedNewProvider);
|
||||
|
||||
let providersAfter = yield SocialService.getProviderList(next);
|
||||
do_check_eq(providersAfter.length, originalProviders.length + 1);
|
||||
do_check_neq(providersAfter.indexOf(newProvider), -1);
|
||||
|
||||
// Now remove the provider
|
||||
yield SocialService.disableProvider(newProvider.origin, next);
|
||||
providersAfter = yield SocialService.getProviderList(next);
|
||||
do_check_eq(providersAfter.length, originalProviders.length);
|
||||
do_check_eq(providersAfter.indexOf(newProvider), -1);
|
||||
newProvider = yield SocialService.getProvider(newProvider.origin, next);
|
||||
do_check_true(!newProvider);
|
||||
}
|
||||
|
||||
function* testIsSameOrigin(manifests, next) {
|
||||
let providers = yield SocialService.getProviderList(next);
|
||||
let provider = providers[0];
|
||||
// provider.origin is a string.
|
||||
do_check_true(provider.isSameOrigin(provider.origin));
|
||||
do_check_true(provider.isSameOrigin(Services.io.newURI(provider.origin)));
|
||||
do_check_true(provider.isSameOrigin(provider.origin + "/some-sub-page"));
|
||||
do_check_true(provider.isSameOrigin(Services.io.newURI(provider.origin + "/some-sub-page")));
|
||||
do_check_false(provider.isSameOrigin("http://something.com"));
|
||||
do_check_false(provider.isSameOrigin(Services.io.newURI("http://something.com")));
|
||||
do_check_false(provider.isSameOrigin("data:text/html,<p>hi"));
|
||||
do_check_true(provider.isSameOrigin("data:text/html,<p>hi", true));
|
||||
do_check_false(provider.isSameOrigin(Services.io.newURI("data:text/html,<p>hi")));
|
||||
do_check_true(provider.isSameOrigin(Services.io.newURI("data:text/html,<p>hi"), true));
|
||||
// we explicitly handle null and return false
|
||||
do_check_false(provider.isSameOrigin(null));
|
||||
}
|
||||
|
||||
function* testResolveUri(manifests, next) {
|
||||
let providers = yield SocialService.getProviderList(next);
|
||||
let provider = providers[0];
|
||||
do_check_eq(provider.resolveUri(provider.origin).spec, provider.origin + "/");
|
||||
do_check_eq(provider.resolveUri("foo.html").spec, provider.origin + "/foo.html");
|
||||
do_check_eq(provider.resolveUri("/foo.html").spec, provider.origin + "/foo.html");
|
||||
do_check_eq(provider.resolveUri("http://somewhereelse.com/foo.html").spec, "http://somewhereelse.com/foo.html");
|
||||
do_check_eq(provider.resolveUri("data:text/html,<p>hi").spec, "data:text/html,<p>hi");
|
||||
}
|
||||
|
||||
function* testOrderedProviders(manifests, next) {
|
||||
let providers = yield SocialService.getProviderList(next);
|
||||
|
||||
// add visits for only one of the providers
|
||||
let visits = [];
|
||||
let startDate = Date.now() * 1000;
|
||||
for (let i = 0; i < 10; i++) {
|
||||
visits.push({
|
||||
uri: Services.io.newURI(providers[1].shareURL + i),
|
||||
visitDate: startDate + i
|
||||
});
|
||||
}
|
||||
|
||||
PlacesTestUtils.addVisits(visits).then(next);
|
||||
yield;
|
||||
let orderedProviders = yield SocialService.getOrderedProviderList(next);
|
||||
do_check_eq(orderedProviders[0], providers[1]);
|
||||
do_check_eq(orderedProviders[1], providers[0]);
|
||||
do_check_true(orderedProviders[0].frecency > orderedProviders[1].frecency);
|
||||
PlacesTestUtils.clearHistory().then(next);
|
||||
yield;
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
/* 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/. */
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
const DEFAULT_PREFS = Services.prefs.getDefaultBranch("social.manifest.");
|
||||
|
||||
function run_test() {
|
||||
// Test must run at startup for migration to occur, so we can only test
|
||||
// one migration per test file
|
||||
initApp();
|
||||
|
||||
// NOTE: none of the manifests here can have a workerURL set, or we attempt
|
||||
// to create a FrameWorker and that fails under xpcshell...
|
||||
let manifest = { // normal provider
|
||||
name: "provider 1",
|
||||
origin: "https://example1.com",
|
||||
builtin: true // as of fx22 this should be true for default prefs
|
||||
};
|
||||
|
||||
DEFAULT_PREFS.setCharPref(manifest.origin, JSON.stringify(manifest));
|
||||
Services.prefs.setBoolPref("social.active", true);
|
||||
|
||||
Cu.import("resource:///modules/SocialService.jsm");
|
||||
|
||||
let runner = new AsyncRunner();
|
||||
let next = runner.next.bind(runner);
|
||||
runner.appendIterator(testMigration(manifest, next));
|
||||
runner.next();
|
||||
}
|
||||
|
||||
function* testMigration(manifest, next) {
|
||||
// look at social.activeProviders, we should have migrated into that, and
|
||||
// we should be set as a user level pref after migration
|
||||
do_check_false(MANIFEST_PREFS.prefHasUserValue(manifest.origin));
|
||||
// we need to access the providers for everything to initialize
|
||||
yield SocialService.getProviderList(next);
|
||||
do_check_true(SocialService.enabled);
|
||||
do_check_true(Services.prefs.prefHasUserValue("social.activeProviders"));
|
||||
|
||||
let activeProviders =
|
||||
JSON.parse(Services.prefs.getStringPref("social.activeProviders"));
|
||||
do_check_true(activeProviders[manifest.origin]);
|
||||
do_check_true(MANIFEST_PREFS.prefHasUserValue(manifest.origin));
|
||||
do_check_true(JSON.parse(DEFAULT_PREFS.getCharPref(manifest.origin)).builtin);
|
||||
|
||||
let userPref = JSON.parse(MANIFEST_PREFS.getCharPref(manifest.origin));
|
||||
do_check_true(parseInt(userPref.updateDate) > 0);
|
||||
// migrated providers wont have an installDate
|
||||
do_check_true(userPref.installDate === 0);
|
||||
}
|
|
@ -1,62 +0,0 @@
|
|||
/* 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/. */
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
const DEFAULT_PREFS = Services.prefs.getDefaultBranch("social.manifest.");
|
||||
|
||||
function run_test() {
|
||||
// Test must run at startup for migration to occur, so we can only test
|
||||
// one migration per test file
|
||||
initApp();
|
||||
|
||||
// NOTE: none of the manifests here can have a workerURL set, or we attempt
|
||||
// to create a FrameWorker and that fails under xpcshell...
|
||||
let manifest = { // normal provider
|
||||
name: "provider 1",
|
||||
origin: "https://example1.com",
|
||||
builtin: true // as of fx22 this should be true for default prefs
|
||||
};
|
||||
|
||||
DEFAULT_PREFS.setCharPref(manifest.origin, JSON.stringify(manifest));
|
||||
|
||||
// Set both providers active and flag the first one as "current"
|
||||
let active = {};
|
||||
active[manifest.origin] = 1;
|
||||
// bad.origin tests that a missing manifest does not break migration, bug 859715
|
||||
active["bad.origin"] = 1;
|
||||
Services.prefs.setStringPref("social.activeProviders",
|
||||
JSON.stringify(active));
|
||||
|
||||
Cu.import("resource:///modules/SocialService.jsm");
|
||||
|
||||
let runner = new AsyncRunner();
|
||||
let next = runner.next.bind(runner);
|
||||
runner.appendIterator(testMigration(manifest, next));
|
||||
runner.next();
|
||||
}
|
||||
|
||||
function* testMigration(manifest, next) {
|
||||
// look at social.activeProviders, we should have migrated into that, and
|
||||
// we should be set as a user level pref after migration
|
||||
do_check_false(MANIFEST_PREFS.prefHasUserValue(manifest.origin));
|
||||
// we need to access the providers for everything to initialize
|
||||
yield SocialService.getProviderList(next);
|
||||
do_check_true(SocialService.enabled);
|
||||
do_check_true(Services.prefs.prefHasUserValue("social.activeProviders"));
|
||||
|
||||
let activeProviders =
|
||||
JSON.parse(Services.prefs.getStringPref("social.activeProviders"));
|
||||
do_check_true(activeProviders[manifest.origin]);
|
||||
do_check_true(MANIFEST_PREFS.prefHasUserValue(manifest.origin));
|
||||
do_check_true(JSON.parse(DEFAULT_PREFS.getCharPref(manifest.origin)).builtin);
|
||||
|
||||
let userPref = JSON.parse(MANIFEST_PREFS.getCharPref(manifest.origin));
|
||||
do_check_true(parseInt(userPref.updateDate) > 0);
|
||||
// migrated providers wont have an installDate
|
||||
do_check_true(userPref.installDate === 0);
|
||||
|
||||
// bug 859715, this should have been removed during migration
|
||||
do_check_false(!!activeProviders["bad.origin"]);
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
/* 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/. */
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
|
||||
function run_test() {
|
||||
// Test must run at startup for migration to occur, so we can only test
|
||||
// one migration per test file
|
||||
initApp();
|
||||
|
||||
// NOTE: none of the manifests here can have a workerURL set, or we attempt
|
||||
// to create a FrameWorker and that fails under xpcshell...
|
||||
let manifest = { // normal provider
|
||||
name: "provider 1",
|
||||
origin: "https://example1.com",
|
||||
};
|
||||
|
||||
MANIFEST_PREFS.setCharPref(manifest.origin, JSON.stringify(manifest));
|
||||
|
||||
// Set both providers active and flag the first one as "current"
|
||||
let active = {};
|
||||
active[manifest.origin] = 1;
|
||||
Services.prefs.setStringPref("social.activeProviders",
|
||||
JSON.stringify(active));
|
||||
|
||||
// social.enabled pref is the key focus of this test. We set the user pref,
|
||||
// and then migration should a) remove the provider from activeProviders and
|
||||
// b) unset social.enabled
|
||||
Services.prefs.setBoolPref("social.enabled", false);
|
||||
|
||||
Cu.import("resource:///modules/SocialService.jsm");
|
||||
|
||||
let runner = new AsyncRunner();
|
||||
let next = runner.next.bind(runner);
|
||||
runner.appendIterator(testMigration(manifest, next));
|
||||
runner.next();
|
||||
}
|
||||
|
||||
function* testMigration(manifest, next) {
|
||||
// look at social.activeProviders, we should have migrated into that, and
|
||||
// we should be set as a user level pref after migration
|
||||
do_check_true(Services.prefs.prefHasUserValue("social.enabled"));
|
||||
do_check_true(MANIFEST_PREFS.prefHasUserValue(manifest.origin));
|
||||
// we need to access the providers for everything to initialize
|
||||
yield SocialService.getProviderList(next);
|
||||
do_check_false(SocialService.enabled);
|
||||
do_check_false(Services.prefs.prefHasUserValue("social.enabled"));
|
||||
do_check_true(Services.prefs.prefHasUserValue("social.activeProviders"));
|
||||
|
||||
let activeProviders;
|
||||
let pref = Services.prefs.getStringPref("social.activeProviders");
|
||||
activeProviders = JSON.parse(pref);
|
||||
do_check_true(activeProviders[manifest.origin] == undefined);
|
||||
do_check_true(MANIFEST_PREFS.prefHasUserValue(manifest.origin));
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
/* 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/. */
|
||||
|
||||
function run_test() {
|
||||
// we are testing worker startup specifically
|
||||
do_test_pending();
|
||||
add_test(testStartupEnabled);
|
||||
add_test(testDisableAfterStartup);
|
||||
do_initialize_social(true, run_next_test);
|
||||
}
|
||||
|
||||
function testStartupEnabled() {
|
||||
// wait on startup before continuing
|
||||
do_check_eq(Social.providers.length, 2, "two social providers enabled");
|
||||
do_check_true(Social.providers[0].enabled, "provider 0 is enabled");
|
||||
do_check_true(Social.providers[1].enabled, "provider 1 is enabled");
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function testDisableAfterStartup() {
|
||||
let SocialService = Cu.import("resource:///modules/SocialService.jsm", {}).SocialService;
|
||||
SocialService.disableProvider(Social.providers[0].origin, function() {
|
||||
do_wait_observer("social:providers-changed", function() {
|
||||
do_check_eq(Social.enabled, false, "Social is disabled");
|
||||
do_check_eq(Social.providers.length, 0, "no social providers available");
|
||||
do_test_finished();
|
||||
run_next_test();
|
||||
});
|
||||
SocialService.disableProvider(Social.providers[0].origin)
|
||||
});
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
/* 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/. */
|
||||
|
||||
function run_test() {
|
||||
// we are testing worker startup specifically
|
||||
do_test_pending();
|
||||
add_test(testStartupDisabled);
|
||||
add_test(testEnableAfterStartup);
|
||||
do_initialize_social(false, run_next_test);
|
||||
}
|
||||
|
||||
function testStartupDisabled() {
|
||||
// wait on startup before continuing
|
||||
do_check_false(Social.enabled, "Social is disabled");
|
||||
do_check_eq(Social.providers.length, 0, "zero social providers available");
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function testEnableAfterStartup() {
|
||||
do_add_providers(function() {
|
||||
do_check_true(Social.enabled, "Social is enabled");
|
||||
do_check_eq(Social.providers.length, 2, "two social providers available");
|
||||
do_check_true(Social.providers[0].enabled, "provider 0 is enabled");
|
||||
do_check_true(Social.providers[1].enabled, "provider 1 is enabled");
|
||||
do_test_finished();
|
||||
run_next_test();
|
||||
});
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
[DEFAULT]
|
||||
head = head.js
|
||||
firefox-appdir = browser
|
||||
skip-if = toolkit == 'android'
|
||||
support-files = blocklist.xml
|
||||
|
||||
[test_social.js]
|
||||
[test_socialDisabledStartup.js]
|
||||
[test_SocialService.js]
|
||||
[test_SocialServiceMigration21.js]
|
||||
[test_SocialServiceMigration22.js]
|
||||
[test_SocialServiceMigration29.js]
|
|
@ -624,56 +624,6 @@ html|span.ac-emphasize-text-url {
|
|||
-moz-image-region: rect(0, 48px, 16px, 32px);
|
||||
}
|
||||
|
||||
/* social share panel */
|
||||
%include ../shared/social/social.inc.css
|
||||
|
||||
.social-share-frame {
|
||||
border-top: 1px solid #f8f8f8;
|
||||
width: 756px;
|
||||
height: 150px;
|
||||
}
|
||||
|
||||
#share-container {
|
||||
min-width: 756px;
|
||||
background-color: white;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
}
|
||||
#share-container[loading] {
|
||||
background-image: url(chrome://browser/skin/tabbrowser/pendingpaint.png);
|
||||
}
|
||||
#share-container > browser {
|
||||
transition: opacity 150ms ease-in-out;
|
||||
opacity: 1;
|
||||
}
|
||||
#share-container[loading] > browser {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.social-share-toolbar {
|
||||
border-bottom: 1px solid #dedede;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
#social-share-provider-buttons {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.share-provider-button {
|
||||
padding: 5px;
|
||||
margin: 2px;
|
||||
}
|
||||
|
||||
.share-provider-button > .toolbarbutton-text {
|
||||
display: none;
|
||||
}
|
||||
.share-provider-button > .toolbarbutton-icon {
|
||||
width: 16px;
|
||||
min-height: 16px;
|
||||
max-height: 16px;
|
||||
}
|
||||
|
||||
/* Bookmarking panel */
|
||||
#editBookmarkPanelStarIcon {
|
||||
list-style-image: url("chrome://browser/skin/places/starred48.png");
|
||||
|
|
|
@ -49,14 +49,6 @@
|
|||
padding-inline-start: 0;
|
||||
}
|
||||
|
||||
/* subviewbutton entries for social sidebars have images that come from external
|
||||
/* sources, and are not guaranteed to be the size we want, so force the size on
|
||||
/* those icons. */
|
||||
toolbarbutton.social-provider-menuitem > .toolbarbutton-icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.subviewbutton:-moz-any([image],[targetURI],.cui-withicon, .restoreallitem, .bookmark-item)[checked="true"] > .toolbarbutton-icon {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
|
|
@ -64,8 +64,6 @@ browser.jar:
|
|||
* skin/classic/browser/preferences/in-content/dialog.css (preferences/in-content/dialog.css)
|
||||
* skin/classic/browser/preferences/in-content-new/dialog.css (preferences/in-content-new/dialog.css)
|
||||
skin/classic/browser/preferences/applications.css (preferences/applications.css)
|
||||
skin/classic/browser/social/services-16.png (social/services-16.png)
|
||||
skin/classic/browser/social/services-64.png (social/services-64.png)
|
||||
skin/classic/browser/tabbrowser/tabDragIndicator.png (tabbrowser/tabDragIndicator.png)
|
||||
|
||||
skin/classic/browser/sync-desktopIcon.svg (../shared/sync-desktopIcon.svg)
|
||||
|
|
|
@ -3,8 +3,46 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* Sidebars */
|
||||
|
||||
#sidebar-search-container {
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
#search-box {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#viewButton {
|
||||
-moz-appearance: none;
|
||||
border-radius: 4px;
|
||||
margin: 1px 0;
|
||||
margin-inline-start: 4px;
|
||||
padding: 2px 4px;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
#viewButton:-moz-focusring:not(:hover):not([open]) {
|
||||
outline: 1px dotted -moz-DialogText;
|
||||
}
|
||||
|
||||
#viewButton:hover {
|
||||
background: hsla(240, 5%, 5%, 0.1);
|
||||
}
|
||||
|
||||
#viewButton[open] {
|
||||
background: hsla(240, 5%, 5%, 0.15);
|
||||
}
|
||||
|
||||
.sidebar-placesTree {
|
||||
margin: 0;
|
||||
color: inherit;
|
||||
-moz-appearance: none;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.sidebar-placesTreechildren::-moz-tree-row {
|
||||
min-height: 24px;
|
||||
}
|
||||
|
||||
.sidebar-placesTreechildren::-moz-tree-cell(leaf) ,
|
||||
|
|
|
@ -674,55 +674,6 @@ html|span.ac-emphasize-text-url {
|
|||
-moz-image-region: rect(0, 48px, 16px, 32px);
|
||||
}
|
||||
|
||||
/* social share panel */
|
||||
.social-share-frame {
|
||||
border-top: 1px solid #f8f8f8;
|
||||
min-width: 756px;
|
||||
height: 150px;
|
||||
/* we resize our panels dynamically, make it look nice */
|
||||
}
|
||||
|
||||
#share-container {
|
||||
min-width: 756px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
}
|
||||
#share-container[loading] {
|
||||
background-image: url(chrome://browser/skin/tabbrowser/pendingpaint.png);
|
||||
}
|
||||
#share-container > browser {
|
||||
transition: opacity 150ms ease-in-out;
|
||||
opacity: 1;
|
||||
}
|
||||
#share-container[loading] > browser {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.social-share-toolbar {
|
||||
border-bottom: 1px solid #dedede;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
#social-share-provider-buttons {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.share-provider-button {
|
||||
padding: 5px;
|
||||
margin: 2px;
|
||||
}
|
||||
|
||||
.share-provider-button > .toolbarbutton-text {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.share-provider-button > .toolbarbutton-icon {
|
||||
width: 16px;
|
||||
min-height: 16px;
|
||||
max-height: 16px;
|
||||
}
|
||||
|
||||
/* BOOKMARKING PANEL */
|
||||
#editBookmarkPanelStarIcon {
|
||||
list-style-image: url("chrome://browser/skin/places/starred48.png");
|
||||
|
@ -1420,33 +1371,6 @@ html|*.addon-webext-perm-list {
|
|||
border-radius: 1px;
|
||||
}
|
||||
|
||||
/* Share */
|
||||
%include ../shared/social/social.inc.css
|
||||
|
||||
#social-share-panel {
|
||||
min-height: 100px;
|
||||
min-width: 300px;
|
||||
transition: height .3s ease-in-out, width .3s ease-in-out;
|
||||
}
|
||||
|
||||
#share-container,
|
||||
.social-share-frame {
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: inherit;
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: inherit;
|
||||
}
|
||||
|
||||
#social-share-panel > .social-share-toolbar {
|
||||
border-top-left-radius: inherit;
|
||||
border-top-right-radius: inherit;
|
||||
}
|
||||
|
||||
#social-share-provider-buttons {
|
||||
border-top-left-radius: inherit;
|
||||
border-top-right-radius: inherit;
|
||||
}
|
||||
|
||||
/* Customization mode */
|
||||
|
||||
%include ../shared/customizableui/customizeMode.inc.css
|
||||
|
|
|
@ -95,10 +95,6 @@ browser.jar:
|
|||
* skin/classic/browser/preferences/in-content/dialog.css (preferences/in-content/dialog.css)
|
||||
* skin/classic/browser/preferences/in-content-new/dialog.css (preferences/in-content-new/dialog.css)
|
||||
skin/classic/browser/preferences/applications.css (preferences/applications.css)
|
||||
skin/classic/browser/social/services-16.png (social/services-16.png)
|
||||
skin/classic/browser/social/services-16@2x.png (social/services-16@2x.png)
|
||||
skin/classic/browser/social/services-64.png (social/services-64.png)
|
||||
skin/classic/browser/social/services-64@2x.png (social/services-64@2x.png)
|
||||
skin/classic/browser/tabbrowser/tabDragIndicator.png (tabbrowser/tabDragIndicator.png)
|
||||
skin/classic/browser/tabbrowser/tabDragIndicator@2x.png (tabbrowser/tabDragIndicator@2x.png)
|
||||
skin/classic/browser/sync-desktopIcon.svg (../shared/sync-desktopIcon.svg)
|
||||
|
|
|
@ -124,7 +124,7 @@
|
|||
padding-inline-start: 5px;
|
||||
padding-inline-end: 0px;
|
||||
margin: 0;
|
||||
margin-inline-end: 4px;
|
||||
margin-inline-start: 4px;
|
||||
min-width: 0px;
|
||||
min-height: 0px;
|
||||
border: 1px solid #a2a9b1;
|
||||
|
@ -159,7 +159,11 @@
|
|||
}
|
||||
|
||||
#sidebar-search-container {
|
||||
margin: 0 4px;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
#search-box {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* Trees */
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
%include aboutSocialError.css
|
||||
|
||||
body {
|
||||
width: 310px;
|
||||
margin: 1em auto;
|
||||
}
|
||||
|
||||
#message-box {
|
||||
margin-top: 2em;
|
||||
background: url(chrome://browser/skin/info.svg) no-repeat left 8px;
|
||||
padding-inline-start: 30px;
|
||||
}
|
||||
|
||||
#activation-frame {
|
||||
border: none;
|
||||
margin: 0;
|
||||
width: 310px;
|
||||
height: 200px;
|
||||
}
|
||||
#activation > p {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
margin: 0;
|
||||
line-height: 2em;
|
||||
}
|
||||
.link {
|
||||
text-decoration: none;
|
||||
color: -moz-nativehyperlinktext;
|
||||
cursor: pointer;
|
||||
}
|
|
@ -93,14 +93,14 @@
|
|||
}
|
||||
|
||||
#PanelUI-button {
|
||||
margin-inline-start: 2px;
|
||||
margin-inline-start: 3px;
|
||||
border-inline-start: 1px solid;
|
||||
border-image: linear-gradient(transparent, rgba(0,0,0,.1) 20%, rgba(0,0,0,.1) 80%, transparent);
|
||||
border-image: linear-gradient(transparent 4px, rgba(0,0,0,.1) 4px, rgba(0,0,0,.1) calc(100% - 4px), transparent calc(100% - 4px));
|
||||
border-image-slice: 1;
|
||||
}
|
||||
|
||||
#nav-bar[brighttext] > #PanelUI-button {
|
||||
border-image-source: linear-gradient(transparent, rgba(100%,100%,100%,.2) 20%, rgba(100%,100%,100%,.2) 80%, transparent);
|
||||
border-image-source: linear-gradient(transparent 4px, rgba(100%,100%,100%,.2) 4px, rgba(100%,100%,100%,.2) calc(100% - 4px), transparent calc(100% - 4px));
|
||||
}
|
||||
|
||||
#PanelUI-menu-button[badge-status] > .toolbarbutton-badge-stack > .toolbarbutton-badge {
|
||||
|
@ -1143,8 +1143,7 @@ toolbaritem[cui-areatype="menu-panel"][sdkstylewidget="true"]:not(.panel-wide-it
|
|||
panelview .toolbarbutton-1,
|
||||
.subviewbutton,
|
||||
.widget-overflow-list .toolbarbutton-1,
|
||||
.panelUI-grid .toolbarbutton-1 > .toolbarbutton-menubutton-button,
|
||||
.share-provider-button {
|
||||
.panelUI-grid .toolbarbutton-1 > .toolbarbutton-menubutton-button {
|
||||
-moz-appearance: none;
|
||||
padding: 0 6px;
|
||||
background-color: transparent;
|
||||
|
@ -1155,8 +1154,7 @@ panelview .toolbarbutton-1,
|
|||
|
||||
panelview .toolbarbutton-1,
|
||||
.subviewbutton,
|
||||
.widget-overflow-list .toolbarbutton-1,
|
||||
.share-provider-button {
|
||||
.widget-overflow-list .toolbarbutton-1 {
|
||||
border-width: 1px;
|
||||
}
|
||||
|
||||
|
@ -1370,7 +1368,6 @@ panelview .toolbarbutton-1@buttonStateHover@,
|
|||
toolbarbutton.subviewbutton@buttonStateHover@,
|
||||
menu.subviewbutton@menuStateHover@,
|
||||
menuitem.subviewbutton@menuStateHover@,
|
||||
.share-provider-button@buttonStateHover@:not([checked="true"]),
|
||||
.widget-overflow-list .toolbarbutton-1@buttonStateHover@,
|
||||
.toolbaritem-combined-buttons@inAnyPanel@ > toolbarbutton@buttonStateHover@ {
|
||||
background-color: var(--arrowpanel-dimmed);
|
||||
|
@ -1385,7 +1382,6 @@ panelview .toolbarbutton-1:-moz-any(@buttonStateActive@,[checked=true]),
|
|||
toolbarbutton.subviewbutton@buttonStateActive@,
|
||||
menu.subviewbutton@menuStateActive@,
|
||||
menuitem.subviewbutton@menuStateActive@,
|
||||
.share-provider-button:-moz-any(@buttonStateActive@,[checked=true]),
|
||||
.widget-overflow-list .toolbarbutton-1@buttonStateActive@,
|
||||
.toolbaritem-combined-buttons@inAnyPanel@ > toolbarbutton@buttonStateActive@ {
|
||||
background-color: var(--arrowpanel-dimmed-further);
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
<!-- 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="M9 10l5-8-7 8 2 6-4-5H1L15 0v13zm2.6 2.3L9 16v-5z"/>
|
||||
</svg>
|
До Ширина: | Высота: | Размер: 387 B |
|
@ -10,9 +10,7 @@
|
|||
skin/classic/browser/aboutNetError.css (../shared/aboutNetError.css)
|
||||
skin/classic/browser/blockedSite.css (../shared/blockedSite.css)
|
||||
skin/classic/browser/error-pages.css (../shared/error-pages.css)
|
||||
* skin/classic/browser/aboutProviderDirectory.css (../shared/aboutProviderDirectory.css)
|
||||
* skin/classic/browser/aboutSessionRestore.css (../shared/aboutSessionRestore.css)
|
||||
skin/classic/browser/aboutSocialError.css (../shared/aboutSocialError.css)
|
||||
skin/classic/browser/aboutTabCrashed.css (../shared/aboutTabCrashed.css)
|
||||
skin/classic/browser/aboutWelcomeBack.css (../shared/aboutWelcomeBack.css)
|
||||
skin/classic/browser/addons/addon-install-blocked.svg (../shared/addons/addon-install-blocked.svg)
|
||||
|
@ -58,7 +56,6 @@
|
|||
skin/classic/browser/identity-icon.svg (../shared/identity-block/identity-icon.svg)
|
||||
skin/classic/browser/identity-icon-notice.svg (../shared/identity-block/identity-icon-notice.svg)
|
||||
skin/classic/browser/info.svg (../shared/info.svg)
|
||||
* skin/classic/browser/menuPanel-small.svg (../shared/menuPanel-small.svg)
|
||||
|
||||
* skin/classic/browser/notification-icons/camera-blocked.svg (../shared/notification-icons/camera-blocked.svg)
|
||||
* skin/classic/browser/notification-icons/camera.svg (../shared/notification-icons/camera.svg)
|
||||
|
@ -185,7 +182,6 @@
|
|||
skin/classic/browser/reload-to-stop.svg (../shared/icons/reload-to-stop.svg)
|
||||
skin/classic/browser/save.svg (../shared/icons/save.svg)
|
||||
skin/classic/browser/settings.svg (../shared/icons/settings.svg)
|
||||
skin/classic/browser/share.svg (../shared/icons/share.svg)
|
||||
skin/classic/browser/sidebars.svg (../shared/icons/sidebars.svg)
|
||||
skin/classic/browser/sidebars-right.svg (../shared/icons/sidebars-right.svg)
|
||||
skin/classic/browser/stop.svg (../shared/icons/stop.svg)
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- 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="96" height="16" viewBox="0 0 96 16"
|
||||
class="fieldtext">
|
||||
#include icon-colors.inc.svg
|
||||
|
||||
<path id="placeholder" d="M8,16a8,8,0,1,1,8-8A8,8,0,0,1,8,16ZM12,4H4v8h8V4ZM5,9.939V6.061L6.939,8ZM9.939,11H6.061L8,9.061ZM11,11h0Zm0-4.939V9.939L9.061,8ZM11,5h0ZM6.061,5H9.939L8,6.939Z"/>
|
||||
<path id="cut" d="M29.63,15a2.426,2.426,0,0,1-2.282-1.277c-0.761-1.109-1.694-2.488-1.694-2.488S25,10.329,24.549,9.623a1.05,1.05,0,0,0-1.106-.538S20.6,4.437,20.124,3.706C19.465,2.689,20.7,1,20.7,1l4.4,7.044a19.333,19.333,0,0,0,1.867,2.286c0.519,0.4,1.382-.373,2.8.908C31.7,12.984,31.048,15,29.63,15ZM29.423,12.11c-0.933-1.042-1.728-.908-1.936-0.639a2.093,2.093,0,0,0,.38,1.748,1.612,1.612,0,0,0,1.383.74C29.838,13.959,30.356,13.153,29.423,12.11ZM25.582,7.372L24.4,5.6,27.276,1s1.233,1.69.575,2.708C27.568,4.142,26.445,5.967,25.582,7.372Zm-4.576,2.956A12.482,12.482,0,0,0,22.43,8.645l0.826,1.239c-0.428.65-.937,1.352-0.937,1.352s-0.933,1.378-1.694,2.488A2.426,2.426,0,0,1,18.344,15c-1.417,0-2.074-2.017-.138-3.765C19.624,9.956,20.487,10.732,21.006,10.329ZM18.551,12.11c-0.933,1.042-.415,1.849.173,1.849a1.612,1.612,0,0,0,1.383-.74,2.093,2.093,0,0,0,.38-1.748C20.28,11.2,19.485,11.068,18.551,12.11Z"/>
|
||||
<path id="copy" d="M46,15H40a1,1,0,0,1-1-1V6a1,1,0,0,1,1-1h4.953C45,5,47,6.984,47,7.047V14A1,1,0,0,1,46,15ZM44,6V8h2ZM38,4.886V11H34a1,1,0,0,1-1-1V2a1,1,0,0,1,1-1h4.953C39,1,41,2.985,41,3.047v1.34H38.5A0.5,0.5,0,0,0,38,4.886ZM38,2V4h2Z"/>
|
||||
<path id="paste" d="M59.5,15h-7A1.5,1.5,0,0,1,51,13.5v-9A1.5,1.5,0,0,1,52.5,3H54a2,2,0,1,1,4,0h1.5A1.5,1.5,0,0,1,61,4.5v9A1.5,1.5,0,0,1,59.5,15ZM58.682,4L57.61,3.5a1.613,1.613,0,0,0-3.219,0L53.318,4,52.781,5h6.437ZM58.82,5.688H54.074L51.059,7.428l2.849,4.935,6.574-3.8Z"/>
|
||||
<rect id="zoomOut" x="67" y="7" width="10" height="2"/>
|
||||
<path id="zoomIn" d="M93,9H89v4H87V9H83V7h4V3h2V7h4V9Z"/>
|
||||
</svg>
|
До Ширина: | Высота: | Размер: 2.1 KiB |
|
@ -1,10 +1,5 @@
|
|||
/* Menu panel and palette styles */
|
||||
|
||||
#add-share-provider {
|
||||
list-style-image: url(chrome://browser/skin/menuPanel-small.svg);
|
||||
-moz-image-region: rect(0px, 96px, 16px, 80px);
|
||||
}
|
||||
|
||||
#appMenuRecentlyClosedWindows,
|
||||
#appMenu-new-window-button {
|
||||
list-style-image: url(chrome://browser/skin/new-window.svg);
|
||||
|
|
|
@ -300,28 +300,6 @@ html|*#webRTC-previewVideo {
|
|||
}
|
||||
}
|
||||
|
||||
/* SOCIAL API */
|
||||
|
||||
.popup-notification-icon[popupid="servicesInstall"] {
|
||||
list-style-image: url(chrome://browser/skin/social/services-64.png);
|
||||
}
|
||||
|
||||
.service-icon {
|
||||
list-style-image: url(chrome://browser/skin/social/services-16.png);
|
||||
}
|
||||
|
||||
%ifdef XP_MACOSX
|
||||
@media (min-resolution: 1.1dppx) {
|
||||
.popup-notification-icon[popupid="servicesInstall"] {
|
||||
list-style-image: url(chrome://browser/skin/social/services-64@2x.png);
|
||||
}
|
||||
|
||||
.service-icon {
|
||||
list-style-image: url(chrome://browser/skin/social/services-16@2x.png);
|
||||
}
|
||||
}
|
||||
%endif
|
||||
|
||||
/* TRANSLATION */
|
||||
|
||||
.translation-icon {
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
%if 0
|
||||
/* 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/. */
|
||||
%endif
|
||||
|
||||
#manage-share-providers {
|
||||
list-style-image: url("chrome://browser/skin/settings.svg");
|
||||
-moz-context-properties: fill;
|
||||
fill: currentColor;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.social-panel > .panel-arrowcontainer > .panel-arrowcontent {
|
||||
padding: 0;
|
||||
}
|
||||
/* fixup corners for share panel */
|
||||
.social-panel > .social-panel-frame {
|
||||
border-radius: inherit;
|
||||
}
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче