зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1289549 P1 socialapi remove status and marks, r=florian
MozReview-Commit-ID: 5fT51pp97Tm
This commit is contained in:
Родитель
cea21d820c
Коммит
94bc4d9381
|
@ -93,10 +93,6 @@
|
||||||
label="&saveLinkCmd.label;"
|
label="&saveLinkCmd.label;"
|
||||||
accesskey="&saveLinkCmd.accesskey;"
|
accesskey="&saveLinkCmd.accesskey;"
|
||||||
oncommand="gContextMenu.saveLink();"/>
|
oncommand="gContextMenu.saveLink();"/>
|
||||||
<menu id="context-marklinkMenu" label="&social.marklinkMenu.label;"
|
|
||||||
accesskey="&social.marklinkMenu.accesskey;">
|
|
||||||
<menupopup/>
|
|
||||||
</menu>
|
|
||||||
<menuitem id="context-copyemail"
|
<menuitem id="context-copyemail"
|
||||||
label="©EmailCmd.label;"
|
label="©EmailCmd.label;"
|
||||||
accesskey="©EmailCmd.accesskey;"
|
accesskey="©EmailCmd.accesskey;"
|
||||||
|
@ -291,10 +287,6 @@
|
||||||
<menupopup id="context-sendpagetodevice-popup"
|
<menupopup id="context-sendpagetodevice-popup"
|
||||||
onpopupshowing="(() => { let browser = gBrowser || getPanelBrowser(); gFxAccounts.populateSendTabToDevicesMenu(event.target, browser.currentURI.spec, browser.contentTitle); })()"/>
|
onpopupshowing="(() => { let browser = gBrowser || getPanelBrowser(); gFxAccounts.populateSendTabToDevicesMenu(event.target, browser.currentURI.spec, browser.contentTitle); })()"/>
|
||||||
</menu>
|
</menu>
|
||||||
<menu id="context-markpageMenu" label="&social.markpageMenu.label;"
|
|
||||||
accesskey="&social.markpageMenu.accesskey;">
|
|
||||||
<menupopup/>
|
|
||||||
</menu>
|
|
||||||
<menuseparator id="context-sep-viewbgimage"/>
|
<menuseparator id="context-sep-viewbgimage"/>
|
||||||
<menuitem id="context-viewbgimage"
|
<menuitem id="context-viewbgimage"
|
||||||
label="&viewBGImageCmd.label;"
|
label="&viewBGImageCmd.label;"
|
||||||
|
|
|
@ -121,7 +121,7 @@
|
||||||
</commandset>
|
</commandset>
|
||||||
|
|
||||||
<broadcasterset id="mainBroadcasterSet">
|
<broadcasterset id="mainBroadcasterSet">
|
||||||
<broadcaster id="Social:PageShareOrMark" disabled="true"/>
|
<broadcaster id="Social:PageShareable" disabled="true"/>
|
||||||
<broadcaster id="viewBookmarksSidebar" autoCheck="false" label="&bookmarksButton.label;"
|
<broadcaster id="viewBookmarksSidebar" autoCheck="false" label="&bookmarksButton.label;"
|
||||||
type="checkbox" group="sidebar" sidebarurl="chrome://browser/content/bookmarks/bookmarksPanel.xul"
|
type="checkbox" group="sidebar" sidebarurl="chrome://browser/content/bookmarks/bookmarksPanel.xul"
|
||||||
oncommand="SidebarUI.toggle('viewBookmarksSidebar');"/>
|
oncommand="SidebarUI.toggle('viewBookmarksSidebar');"/>
|
||||||
|
@ -316,7 +316,6 @@
|
||||||
<key id="viewBookmarksSidebarWinKb" key="&bookmarksWinCmd.commandkey;" command="viewBookmarksSidebar" modifiers="accel"/>
|
<key id="viewBookmarksSidebarWinKb" key="&bookmarksWinCmd.commandkey;" command="viewBookmarksSidebar" modifiers="accel"/>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
<!--<key id="markPage" key="&markPageCmd.commandkey;" command="Social:TogglePageMark" modifiers="accel,shift"/>-->
|
|
||||||
<key id="focusChatBar" key="&social.chatBar.commandkey;" command="Chat:Focus"
|
<key id="focusChatBar" key="&social.chatBar.commandkey;" command="Chat:Focus"
|
||||||
#ifdef XP_MACOSX
|
#ifdef XP_MACOSX
|
||||||
# Sadly the devtools uses shift-accel-c on non-mac and alt-accel-c everywhere else
|
# Sadly the devtools uses shift-accel-c on non-mac and alt-accel-c everywhere else
|
||||||
|
|
|
@ -5,10 +5,8 @@
|
||||||
// the "exported" symbols
|
// the "exported" symbols
|
||||||
var SocialUI,
|
var SocialUI,
|
||||||
SocialFlyout,
|
SocialFlyout,
|
||||||
SocialMarks,
|
|
||||||
SocialShare,
|
SocialShare,
|
||||||
SocialSidebar,
|
SocialSidebar,
|
||||||
SocialStatus,
|
|
||||||
SocialActivationListener;
|
SocialActivationListener;
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
@ -34,18 +32,6 @@ XPCOMUtils.defineLazyGetter(this, "sizeSocialPanelToContent", function() {
|
||||||
return tmp.sizeSocialPanelToContent;
|
return tmp.sizeSocialPanelToContent;
|
||||||
});
|
});
|
||||||
|
|
||||||
XPCOMUtils.defineLazyGetter(this, "CreateSocialStatusWidget", function() {
|
|
||||||
let tmp = {};
|
|
||||||
Cu.import("resource:///modules/Social.jsm", tmp);
|
|
||||||
return tmp.CreateSocialStatusWidget;
|
|
||||||
});
|
|
||||||
|
|
||||||
XPCOMUtils.defineLazyGetter(this, "CreateSocialMarkWidget", function() {
|
|
||||||
let tmp = {};
|
|
||||||
Cu.import("resource:///modules/Social.jsm", tmp);
|
|
||||||
return tmp.CreateSocialMarkWidget;
|
|
||||||
});
|
|
||||||
|
|
||||||
XPCOMUtils.defineLazyGetter(this, "hookWindowCloseForPanelClose", function() {
|
XPCOMUtils.defineLazyGetter(this, "hookWindowCloseForPanelClose", function() {
|
||||||
let tmp = {};
|
let tmp = {};
|
||||||
Cu.import("resource://gre/modules/MozSocialAPI.jsm", tmp);
|
Cu.import("resource://gre/modules/MozSocialAPI.jsm", tmp);
|
||||||
|
@ -127,16 +113,11 @@ SocialUI = {
|
||||||
observe: function SocialUI_observe(subject, topic, data) {
|
observe: function SocialUI_observe(subject, topic, data) {
|
||||||
switch (topic) {
|
switch (topic) {
|
||||||
case "social:provider-enabled":
|
case "social:provider-enabled":
|
||||||
SocialMarks.populateToolbarPalette();
|
|
||||||
SocialStatus.populateToolbarPalette();
|
|
||||||
break;
|
break;
|
||||||
case "social:provider-disabled":
|
case "social:provider-disabled":
|
||||||
SocialMarks.removeProvider(data);
|
|
||||||
SocialStatus.removeProvider(data);
|
|
||||||
SocialSidebar.disableProvider(data);
|
SocialSidebar.disableProvider(data);
|
||||||
break;
|
break;
|
||||||
case "social:provider-reload":
|
case "social:provider-reload":
|
||||||
SocialStatus.reloadProvider(data);
|
|
||||||
// if the reloaded provider is our current provider, fall through
|
// if the reloaded provider is our current provider, fall through
|
||||||
// to social:providers-changed so the ui will be reset
|
// to social:providers-changed so the ui will be reset
|
||||||
if (!SocialSidebar.provider || SocialSidebar.provider.origin != data)
|
if (!SocialSidebar.provider || SocialSidebar.provider.origin != data)
|
||||||
|
@ -154,7 +135,6 @@ SocialUI = {
|
||||||
break;
|
break;
|
||||||
// Provider-specific notifications
|
// Provider-specific notifications
|
||||||
case "social:ambient-notification-changed":
|
case "social:ambient-notification-changed":
|
||||||
SocialStatus.updateButton(data);
|
|
||||||
break;
|
break;
|
||||||
case "nsPref:changed":
|
case "nsPref:changed":
|
||||||
if (data == "social.toast-notifications.enabled") {
|
if (data == "social.toast-notifications.enabled") {
|
||||||
|
@ -168,8 +148,6 @@ SocialUI = {
|
||||||
SocialSidebar.clearProviderMenus();
|
SocialSidebar.clearProviderMenus();
|
||||||
SocialSidebar.update();
|
SocialSidebar.update();
|
||||||
SocialShare.populateProviderMenu();
|
SocialShare.populateProviderMenu();
|
||||||
SocialStatus.populateToolbarPalette();
|
|
||||||
SocialMarks.populateToolbarPalette();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
showLearnMore: function() {
|
showLearnMore: function() {
|
||||||
|
@ -219,7 +197,7 @@ SocialUI = {
|
||||||
return Social.providers.length > 0;
|
return Social.providers.length > 0;
|
||||||
},
|
},
|
||||||
|
|
||||||
canShareOrMarkPage: function(aURI) {
|
canSharePage: function(aURI) {
|
||||||
return (aURI && (aURI.schemeIs('http') || aURI.schemeIs('https')));
|
return (aURI && (aURI.schemeIs('http') || aURI.schemeIs('https')));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -228,7 +206,7 @@ SocialUI = {
|
||||||
return;
|
return;
|
||||||
// customization mode gets buttons out of sync with command updating, fix
|
// customization mode gets buttons out of sync with command updating, fix
|
||||||
// the disabled state
|
// the disabled state
|
||||||
let canShare = this.canShareOrMarkPage(gBrowser.currentURI);
|
let canShare = this.canSharePage(gBrowser.currentURI);
|
||||||
let shareButton = SocialShare.shareButton;
|
let shareButton = SocialShare.shareButton;
|
||||||
if (shareButton) {
|
if (shareButton) {
|
||||||
if (canShare) {
|
if (canShare) {
|
||||||
|
@ -237,24 +215,12 @@ SocialUI = {
|
||||||
shareButton.setAttribute("disabled", "true")
|
shareButton.setAttribute("disabled", "true")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// update the disabled state of the button based on the command
|
|
||||||
for (let node of SocialMarks.nodes) {
|
|
||||||
if (canShare) {
|
|
||||||
node.removeAttribute("disabled")
|
|
||||||
} else {
|
|
||||||
node.setAttribute("disabled", "true")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// called on tab/urlbar/location changes and after customization. Update
|
// called on tab/urlbar/location changes and after customization. Update
|
||||||
// anything that is tab specific.
|
// anything that is tab specific.
|
||||||
updateState: function() {
|
updateState: function() {
|
||||||
goSetCommandEnabled("Social:PageShareOrMark", this.canShareOrMarkPage(gBrowser.currentURI));
|
goSetCommandEnabled("Social:PageShareable", this.canSharePage(gBrowser.currentURI));
|
||||||
if (!SocialUI.enabled)
|
|
||||||
return;
|
|
||||||
// larger update that may change button icons
|
|
||||||
SocialMarks.update();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -646,7 +612,7 @@ SocialShare = {
|
||||||
let pageData = graphData ? graphData : this.currentShare;
|
let pageData = graphData ? graphData : this.currentShare;
|
||||||
let sharedURI = pageData ? Services.io.newURI(pageData.url, null, null) :
|
let sharedURI = pageData ? Services.io.newURI(pageData.url, null, null) :
|
||||||
gBrowser.currentURI;
|
gBrowser.currentURI;
|
||||||
if (!SocialUI.canShareOrMarkPage(sharedURI))
|
if (!SocialUI.canSharePage(sharedURI))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// the point of this action type is that we can use existing share
|
// the point of this action type is that we can use existing share
|
||||||
|
@ -1097,317 +1063,4 @@ SocialSidebar = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// this helper class is used by removable/customizable buttons to handle
|
|
||||||
// widget creation/destruction
|
|
||||||
|
|
||||||
// When a provider is installed we show all their UI so the user will see the
|
|
||||||
// functionality of what they installed. The user can later customize the UI,
|
|
||||||
// moving buttons around or off the toolbar.
|
|
||||||
//
|
|
||||||
// On startup, we create the button widgets of any enabled provider.
|
|
||||||
// CustomizableUI handles placement and persistence of placement.
|
|
||||||
function ToolbarHelper(type, createButtonFn, listener) {
|
|
||||||
this._createButton = createButtonFn;
|
|
||||||
this._type = type;
|
|
||||||
|
|
||||||
if (listener) {
|
|
||||||
CustomizableUI.addListener(listener);
|
|
||||||
// remove this listener on window close
|
|
||||||
window.addEventListener("unload", () => {
|
|
||||||
CustomizableUI.removeListener(listener);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ToolbarHelper.prototype = {
|
|
||||||
idFromOrigin: function(origin) {
|
|
||||||
// this id needs to pass the checks in CustomizableUI, so remove characters
|
|
||||||
// that wont pass.
|
|
||||||
return this._type + "-" + Services.io.newURI(origin, null, null).hostPort.replace(/[\.:]/g,'-');
|
|
||||||
},
|
|
||||||
|
|
||||||
// should be called on disable of a provider
|
|
||||||
removeProviderButton: function(origin) {
|
|
||||||
CustomizableUI.destroyWidget(this.idFromOrigin(origin));
|
|
||||||
},
|
|
||||||
|
|
||||||
clearPalette: function() {
|
|
||||||
for (let p of Social.providers) {
|
|
||||||
this.removeProviderButton(p.origin);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// should be called on enable of a provider
|
|
||||||
populatePalette: function() {
|
|
||||||
if (!Social.enabled) {
|
|
||||||
this.clearPalette();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// create any buttons that do not exist yet if they have been persisted
|
|
||||||
// as a part of the UI (otherwise they belong in the palette).
|
|
||||||
for (let provider of Social.providers) {
|
|
||||||
let id = this.idFromOrigin(provider.origin);
|
|
||||||
this._createButton(id, provider);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var SocialStatusWidgetListener = {
|
|
||||||
_getNodeOrigin: function(aWidgetId) {
|
|
||||||
// we rely on the button id being the same as the widget.
|
|
||||||
let node = document.getElementById(aWidgetId);
|
|
||||||
if (!node)
|
|
||||||
return null
|
|
||||||
if (!node.classList.contains("social-status-button"))
|
|
||||||
return null
|
|
||||||
return node.getAttribute("origin");
|
|
||||||
},
|
|
||||||
onWidgetAdded: function(aWidgetId, aArea, aPosition) {
|
|
||||||
let origin = this._getNodeOrigin(aWidgetId);
|
|
||||||
if (origin)
|
|
||||||
SocialStatus.updateButton(origin);
|
|
||||||
},
|
|
||||||
onWidgetRemoved: function(aWidgetId, aPrevArea) {
|
|
||||||
let origin = this._getNodeOrigin(aWidgetId);
|
|
||||||
if (!origin)
|
|
||||||
return;
|
|
||||||
// When a widget is demoted to the palette ('removed'), it's visual
|
|
||||||
// style should change.
|
|
||||||
SocialStatus.updateButton(origin);
|
|
||||||
SocialStatus._removeFrame(origin);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SocialStatus = {
|
|
||||||
populateToolbarPalette: function() {
|
|
||||||
this._toolbarHelper.populatePalette();
|
|
||||||
|
|
||||||
for (let provider of Social.providers)
|
|
||||||
this.updateButton(provider.origin);
|
|
||||||
},
|
|
||||||
|
|
||||||
removeProvider: function(origin) {
|
|
||||||
this._removeFrame(origin);
|
|
||||||
this._toolbarHelper.removeProviderButton(origin);
|
|
||||||
},
|
|
||||||
|
|
||||||
reloadProvider: function(origin) {
|
|
||||||
let button = document.getElementById(this._toolbarHelper.idFromOrigin(origin));
|
|
||||||
if (button && button.getAttribute("open") == "true")
|
|
||||||
document.getElementById("social-notification-panel").hidePopup();
|
|
||||||
this._removeFrame(origin);
|
|
||||||
},
|
|
||||||
|
|
||||||
_removeFrame: function(origin) {
|
|
||||||
let notificationFrameId = "social-status-" + origin;
|
|
||||||
let frame = document.getElementById(notificationFrameId);
|
|
||||||
if (frame) {
|
|
||||||
frame.parentNode.removeChild(frame);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
get _toolbarHelper() {
|
|
||||||
delete this._toolbarHelper;
|
|
||||||
this._toolbarHelper = new ToolbarHelper("social-status-button",
|
|
||||||
CreateSocialStatusWidget,
|
|
||||||
SocialStatusWidgetListener);
|
|
||||||
return this._toolbarHelper;
|
|
||||||
},
|
|
||||||
|
|
||||||
updateButton: function(origin) {
|
|
||||||
let id = this._toolbarHelper.idFromOrigin(origin);
|
|
||||||
let widget = CustomizableUI.getWidget(id);
|
|
||||||
if (!widget)
|
|
||||||
return;
|
|
||||||
let button = widget.forWindow(window).node;
|
|
||||||
if (button) {
|
|
||||||
// we only grab the first notification, ignore all others
|
|
||||||
let provider = Social._getProviderFromOrigin(origin);
|
|
||||||
let icons = provider.ambientNotificationIcons;
|
|
||||||
let iconNames = Object.keys(icons);
|
|
||||||
let notif = icons[iconNames[0]];
|
|
||||||
|
|
||||||
// The image and tooltip need to be updated for
|
|
||||||
// ambient notification changes.
|
|
||||||
let iconURL = provider.icon32URL || provider.iconURL;
|
|
||||||
let tooltiptext;
|
|
||||||
if (!notif || !widget.areaType) {
|
|
||||||
button.style.listStyleImage = "url(" + iconURL + ")";
|
|
||||||
button.setAttribute("badge", "");
|
|
||||||
button.setAttribute("aria-label", "");
|
|
||||||
button.setAttribute("tooltiptext", provider.name);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
button.style.listStyleImage = "url(" + (notif.iconURL || iconURL) + ")";
|
|
||||||
button.setAttribute("tooltiptext", notif.label || provider.name);
|
|
||||||
|
|
||||||
let badge = notif.counter || "";
|
|
||||||
button.setAttribute("badge", badge);
|
|
||||||
let ariaLabel = notif.label;
|
|
||||||
// if there is a badge value, we must use a localizable string to insert it.
|
|
||||||
if (badge)
|
|
||||||
ariaLabel = gNavigatorBundle.getFormattedString("social.aria.toolbarButtonBadgeText",
|
|
||||||
[ariaLabel, badge]);
|
|
||||||
button.setAttribute("aria-label", ariaLabel);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_onclose: function(frame) {
|
|
||||||
frame.removeEventListener("close", this._onclose, true);
|
|
||||||
frame.removeEventListener("click", this._onclick, true);
|
|
||||||
},
|
|
||||||
|
|
||||||
_onclick: function() {
|
|
||||||
Services.telemetry.getHistogramById("SOCIAL_PANEL_CLICKS").add(1);
|
|
||||||
},
|
|
||||||
|
|
||||||
showPopup: function(aToolbarButton) {
|
|
||||||
// attach our notification panel if necessary
|
|
||||||
let origin = aToolbarButton.getAttribute("origin");
|
|
||||||
let provider = Social._getProviderFromOrigin(origin);
|
|
||||||
|
|
||||||
PanelFrame.showPopup(window, aToolbarButton, "social", origin,
|
|
||||||
provider.statusURL, provider.getPageSize("status"),
|
|
||||||
(frame) => {
|
|
||||||
frame.addEventListener("close", () => { SocialStatus._onclose(frame) }, true);
|
|
||||||
frame.addEventListener("click", this._onclick, true);
|
|
||||||
});
|
|
||||||
Services.telemetry.getHistogramById("SOCIAL_TOOLBAR_BUTTONS").add(1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
var SocialMarksWidgetListener = {
|
|
||||||
onWidgetAdded: function(aWidgetId, aArea, aPosition) {
|
|
||||||
let node = document.getElementById(aWidgetId);
|
|
||||||
if (!node || !node.classList.contains("social-mark-button"))
|
|
||||||
return;
|
|
||||||
node._receiveMessage = node.receiveMessage.bind(node);
|
|
||||||
messageManager.addMessageListener("Social:ErrorPageNotify", node._receiveMessage);
|
|
||||||
},
|
|
||||||
onWidgetBeforeDOMChange: function(aNode, aNextNode, aContainer, isRemoval) {
|
|
||||||
if (!isRemoval || !aNode || !aNode.classList.contains("social-mark-button"))
|
|
||||||
return;
|
|
||||||
messageManager.removeMessageListener("Social:ErrorPageNotify", aNode._receiveMessage);
|
|
||||||
delete aNode._receiveMessage;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SocialMarks
|
|
||||||
*
|
|
||||||
* Handles updates to toolbox and signals all buttons to update when necessary.
|
|
||||||
*/
|
|
||||||
SocialMarks = {
|
|
||||||
get nodes() {
|
|
||||||
for (let p of Social.providers.filter(p => p.markURL)) {
|
|
||||||
let widgetId = SocialMarks._toolbarHelper.idFromOrigin(p.origin);
|
|
||||||
let widget = CustomizableUI.getWidget(widgetId);
|
|
||||||
if (!widget)
|
|
||||||
continue;
|
|
||||||
let node = widget.forWindow(window).node;
|
|
||||||
if (node)
|
|
||||||
yield node;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
update: function() {
|
|
||||||
// querySelectorAll does not work on the menu panel, so we have to do this
|
|
||||||
// the hard way.
|
|
||||||
for (let node of this.nodes) {
|
|
||||||
// xbl binding is not complete on startup when buttons are not in toolbar,
|
|
||||||
// verify update is available
|
|
||||||
if (node.update) {
|
|
||||||
node.update();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
getProviders: function() {
|
|
||||||
// only rely on providers that the user has placed in the UI somewhere. This
|
|
||||||
// also means that populateToolbarPalette must be called prior to using this
|
|
||||||
// method, otherwise you get a big fat zero. For our use case with context
|
|
||||||
// menu's, this is ok.
|
|
||||||
return Social.providers.filter(p => p.markURL &&
|
|
||||||
document.getElementById(this._toolbarHelper.idFromOrigin(p.origin)));
|
|
||||||
},
|
|
||||||
|
|
||||||
populateContextMenu: function() {
|
|
||||||
// only show a selection if enabled and there is more than one
|
|
||||||
let providers = this.getProviders();
|
|
||||||
|
|
||||||
// remove all previous entries by class
|
|
||||||
let menus = [...document.getElementsByClassName("context-socialmarks")];
|
|
||||||
for (let m of menus) {
|
|
||||||
m.parentNode.removeChild(m);
|
|
||||||
}
|
|
||||||
|
|
||||||
let contextMenus = [
|
|
||||||
{
|
|
||||||
type: "link",
|
|
||||||
id: "context-marklinkMenu",
|
|
||||||
label: "social.marklinkMenu.label"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: "page",
|
|
||||||
id: "context-markpageMenu",
|
|
||||||
label: "social.markpageMenu.label"
|
|
||||||
}
|
|
||||||
];
|
|
||||||
for (let cfg of contextMenus) {
|
|
||||||
this._populateContextPopup(cfg, providers);
|
|
||||||
}
|
|
||||||
this.update();
|
|
||||||
},
|
|
||||||
|
|
||||||
MENU_LIMIT: 3, // adjustable for testing
|
|
||||||
_populateContextPopup: function(menuInfo, providers) {
|
|
||||||
let menu = document.getElementById(menuInfo.id);
|
|
||||||
let popup = menu.firstChild;
|
|
||||||
for (let provider of providers) {
|
|
||||||
// We show up to MENU_LIMIT providers as single menuitems's at the top
|
|
||||||
// level of the context menu, if we have more than that, dump them *all*
|
|
||||||
// into the menu popup.
|
|
||||||
let mi = document.createElement("menuitem");
|
|
||||||
mi.setAttribute("oncommand", "gContextMenu.markLink(this.getAttribute('origin'));");
|
|
||||||
mi.setAttribute("origin", provider.origin);
|
|
||||||
mi.setAttribute("image", provider.iconURL);
|
|
||||||
if (providers.length <= this.MENU_LIMIT) {
|
|
||||||
// an extra class to make enable/disable easy
|
|
||||||
mi.setAttribute("class", "menuitem-iconic context-socialmarks context-mark"+menuInfo.type);
|
|
||||||
let menuLabel = gNavigatorBundle.getFormattedString(menuInfo.label, [provider.name]);
|
|
||||||
mi.setAttribute("label", menuLabel);
|
|
||||||
menu.parentNode.insertBefore(mi, menu);
|
|
||||||
} else {
|
|
||||||
mi.setAttribute("class", "menuitem-iconic context-socialmarks");
|
|
||||||
mi.setAttribute("label", provider.name);
|
|
||||||
popup.appendChild(mi);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
populateToolbarPalette: function() {
|
|
||||||
this._toolbarHelper.populatePalette();
|
|
||||||
this.populateContextMenu();
|
|
||||||
},
|
|
||||||
|
|
||||||
removeProvider: function(origin) {
|
|
||||||
this._toolbarHelper.removeProviderButton(origin);
|
|
||||||
},
|
|
||||||
|
|
||||||
get _toolbarHelper() {
|
|
||||||
delete this._toolbarHelper;
|
|
||||||
this._toolbarHelper = new ToolbarHelper("social-mark-button",
|
|
||||||
CreateSocialMarkWidget,
|
|
||||||
SocialMarksWidgetListener);
|
|
||||||
return this._toolbarHelper;
|
|
||||||
},
|
|
||||||
|
|
||||||
markLink: function(aOrigin, aUrl, aTarget) {
|
|
||||||
// find the button for this provider, and open it
|
|
||||||
let id = this._toolbarHelper.idFromOrigin(aOrigin);
|
|
||||||
document.getElementById(id).markLink(aUrl, aTarget);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -350,28 +350,6 @@ nsContextMenu.prototype = {
|
||||||
this.showItem("context-bidi-page-direction-toggle",
|
this.showItem("context-bidi-page-direction-toggle",
|
||||||
!this.onTextInput && top.gBidiUI);
|
!this.onTextInput && top.gBidiUI);
|
||||||
|
|
||||||
// SocialMarks. Marks does not work with text selections, only links. If
|
|
||||||
// there is more than MENU_LIMIT providers, we show a submenu for them,
|
|
||||||
// otherwise we have a menuitem per provider (added in SocialMarks class).
|
|
||||||
let markProviders = SocialMarks.getProviders();
|
|
||||||
let enablePageMarks = markProviders.length > 0 && !(this.onLink || this.onImage
|
|
||||||
|| this.onVideo || this.onAudio);
|
|
||||||
this.showItem("context-markpageMenu", enablePageMarks && markProviders.length > SocialMarks.MENU_LIMIT);
|
|
||||||
let enablePageMarkItems = enablePageMarks && markProviders.length <= SocialMarks.MENU_LIMIT;
|
|
||||||
let linkmenus = document.getElementsByClassName("context-markpage");
|
|
||||||
for (let m of linkmenus) {
|
|
||||||
m.hidden = !enablePageMarkItems;
|
|
||||||
}
|
|
||||||
|
|
||||||
let enableLinkMarks = markProviders.length > 0 &&
|
|
||||||
((this.onLink && !this.onMailtoLink) || this.onPlainTextLink);
|
|
||||||
this.showItem("context-marklinkMenu", enableLinkMarks && markProviders.length > SocialMarks.MENU_LIMIT);
|
|
||||||
let enableLinkMarkItems = enableLinkMarks && markProviders.length <= SocialMarks.MENU_LIMIT;
|
|
||||||
linkmenus = document.getElementsByClassName("context-marklink");
|
|
||||||
for (let m of linkmenus) {
|
|
||||||
m.hidden = !enableLinkMarkItems;
|
|
||||||
}
|
|
||||||
|
|
||||||
// SocialShare
|
// SocialShare
|
||||||
let shareButton = SocialShare.shareButton;
|
let shareButton = SocialShare.shareButton;
|
||||||
let shareEnabled = shareButton && !shareButton.disabled && !this.onSocial;
|
let shareEnabled = shareButton && !shareButton.disabled && !this.onSocial;
|
||||||
|
@ -1732,10 +1710,6 @@ nsContextMenu.prototype = {
|
||||||
mm.sendAsyncMessage("ContextMenu:BookmarkFrame", null, { target: this.target });
|
mm.sendAsyncMessage("ContextMenu:BookmarkFrame", null, { target: this.target });
|
||||||
},
|
},
|
||||||
|
|
||||||
markLink: function CM_markLink(origin) {
|
|
||||||
// send link to social, if it is the page url linkURI will be null
|
|
||||||
SocialMarks.markLink(origin, this.linkURI ? this.linkURI.spec : null, this.target);
|
|
||||||
},
|
|
||||||
shareLink: function CM_shareLink() {
|
shareLink: function CM_shareLink() {
|
||||||
SocialShare.sharePage(null, { url: this.linkURI.spec }, this.target);
|
SocialShare.sharePage(null, { url: this.linkURI.spec }, this.target);
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,366 +0,0 @@
|
||||||
<?xml version="1.0"?>
|
|
||||||
|
|
||||||
<bindings id="socialMarkBindings"
|
|
||||||
xmlns="http://www.mozilla.org/xbl"
|
|
||||||
xmlns:xbl="http://www.mozilla.org/xbl"
|
|
||||||
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
|
||||||
|
|
||||||
|
|
||||||
<binding id="toolbarbutton-marks" display="xul:button"
|
|
||||||
extends="chrome://global/content/bindings/toolbarbutton.xml#toolbarbutton">
|
|
||||||
<content>
|
|
||||||
<xul:panel anonid="panel" hidden="true" type="arrow" class="social-panel"/>
|
|
||||||
<xul:image class="toolbarbutton-icon" xbl:inherits="validate,src=image,label"/>
|
|
||||||
<xul:label class="toolbarbutton-text" crop="right" flex="1"
|
|
||||||
xbl:inherits="value=label,accesskey,crop,wrap"/>
|
|
||||||
<xul:label class="toolbarbutton-multiline-text" flex="1"
|
|
||||||
xbl:inherits="xbl:text=label,accesskey,wrap"/>
|
|
||||||
</content>
|
|
||||||
<implementation implements="nsIDOMEventListener, nsIObserver">
|
|
||||||
<constructor>
|
|
||||||
// if we overflow, we have to reset the button. unfortunately we cannot
|
|
||||||
// use a widget listener because we need to do this *after* the node is
|
|
||||||
// moved, and the event happens before the node is moved.
|
|
||||||
this.update();
|
|
||||||
</constructor>
|
|
||||||
<property name="_anchor">
|
|
||||||
<getter>
|
|
||||||
let widgetGroup = CustomizableUI.getWidget(this.getAttribute("id"));
|
|
||||||
return widgetGroup.forWindow(window).anchor;
|
|
||||||
</getter>
|
|
||||||
</property>
|
|
||||||
<property name="_useDynamicResizer">
|
|
||||||
<getter>
|
|
||||||
let provider = Social._getProviderFromOrigin(this.getAttribute("origin"));
|
|
||||||
return !provider.getPageSize("marks");
|
|
||||||
</getter>
|
|
||||||
</property>
|
|
||||||
|
|
||||||
<property name="panel">
|
|
||||||
<getter>
|
|
||||||
return document.getAnonymousElementByAttribute(this, "anonid", "panel");
|
|
||||||
</getter>
|
|
||||||
</property>
|
|
||||||
|
|
||||||
<property name="content">
|
|
||||||
<getter><![CDATA[
|
|
||||||
if (this._frame)
|
|
||||||
return this._frame;
|
|
||||||
let provider = Social._getProviderFromOrigin(this.getAttribute("origin"));
|
|
||||||
let size = provider.getPageSize("marks");
|
|
||||||
let {width, height} = size ? size : {width: 330, height: 100};
|
|
||||||
|
|
||||||
let iframe = this._frame = document.createElement("iframe");
|
|
||||||
iframe.setAttribute("type", "content");
|
|
||||||
iframe.setAttribute("class", "social-panel-frame");
|
|
||||||
iframe.setAttribute("flex", "1");
|
|
||||||
iframe.setAttribute("message", "true");
|
|
||||||
iframe.setAttribute("messagemanagergroup", "social");
|
|
||||||
iframe.setAttribute("tooltip", "aHTMLTooltip");
|
|
||||||
iframe.setAttribute("context", "contentAreaContextMenu");
|
|
||||||
iframe.setAttribute("origin", provider.origin);
|
|
||||||
iframe.setAttribute("style", "width: " + width + "px; height: " + height + "px;");
|
|
||||||
this.panel.appendChild(iframe);
|
|
||||||
|
|
||||||
this._frame.addEventListener("DOMLinkAdded", this);
|
|
||||||
return this._frame;
|
|
||||||
]]></getter>
|
|
||||||
</property>
|
|
||||||
|
|
||||||
<property name="messageManager">
|
|
||||||
<getter>
|
|
||||||
return this.content.QueryInterface(Components.interfaces.nsIFrameLoaderOwner).frameLoader.messageManager;
|
|
||||||
</getter>
|
|
||||||
</property>
|
|
||||||
|
|
||||||
<property name="contentWindow">
|
|
||||||
<getter>
|
|
||||||
return this.content.contentWindow;
|
|
||||||
</getter>
|
|
||||||
</property>
|
|
||||||
|
|
||||||
<property name="contentDocument">
|
|
||||||
<getter>
|
|
||||||
return this.content.contentDocument;
|
|
||||||
</getter>
|
|
||||||
</property>
|
|
||||||
|
|
||||||
<property name="provider">
|
|
||||||
<getter>
|
|
||||||
return Social._getProviderFromOrigin(this.getAttribute("origin"));
|
|
||||||
</getter>
|
|
||||||
</property>
|
|
||||||
|
|
||||||
<property name="isMarked">
|
|
||||||
<setter><![CDATA[
|
|
||||||
this._isMarked = val;
|
|
||||||
let provider = this.provider;
|
|
||||||
// we cannot size the image when we apply it via listStyleImage, so
|
|
||||||
// use the toolbar image
|
|
||||||
let widgetGroup = CustomizableUI.getWidget(this.getAttribute("id"));
|
|
||||||
val = val && !!widgetGroup.areaType;
|
|
||||||
let icon = val ? provider.markedIcon : provider.unmarkedIcon;
|
|
||||||
let iconURL = icon || provider.icon32URL || provider.iconURL;
|
|
||||||
this.setAttribute("image", iconURL);
|
|
||||||
]]></setter>
|
|
||||||
<getter>
|
|
||||||
return this._isMarked;
|
|
||||||
</getter>
|
|
||||||
</property>
|
|
||||||
|
|
||||||
<method name="update">
|
|
||||||
<body><![CDATA[
|
|
||||||
// update the button for use with the current tab
|
|
||||||
let provider = this.provider;
|
|
||||||
if (this._dynamicResizer) {
|
|
||||||
this._dynamicResizer.stop();
|
|
||||||
this._dynamicResizer = null;
|
|
||||||
}
|
|
||||||
this.content.setAttribute("src", "about:blank");
|
|
||||||
// called during onhidden, make sure the docshell is updated
|
|
||||||
if (this._frame.docShell)
|
|
||||||
this._frame.docShell.createAboutBlankContentViewer(null);
|
|
||||||
|
|
||||||
// disabled attr is set by Social:PageShareOrMark command
|
|
||||||
if (this.hasAttribute("disabled")) {
|
|
||||||
this.isMarked = false;
|
|
||||||
} else {
|
|
||||||
Social.isURIMarked(provider.origin, gBrowser.currentURI, (isMarked) => {
|
|
||||||
this.isMarked = isMarked;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
this.content.setAttribute("origin", provider.origin);
|
|
||||||
|
|
||||||
let panel = this.panel;
|
|
||||||
// if customization is currently happening, we may not have a panel
|
|
||||||
// that we can hide
|
|
||||||
if (panel.hidePopup) {
|
|
||||||
panel.hidePopup();
|
|
||||||
}
|
|
||||||
this.pageData = null;
|
|
||||||
]]></body>
|
|
||||||
</method>
|
|
||||||
|
|
||||||
<method name="receiveMessage">
|
|
||||||
<parameter name="message"/>
|
|
||||||
<body><![CDATA[
|
|
||||||
if (message.name != "Social:ErrorPageNotify" || message.target != this.content)
|
|
||||||
return;
|
|
||||||
this.openPanel();
|
|
||||||
]]></body>
|
|
||||||
</method>
|
|
||||||
|
|
||||||
<method name="loadPanel">
|
|
||||||
<parameter name="pageData"/>
|
|
||||||
<parameter name="target"/>
|
|
||||||
<body><![CDATA[
|
|
||||||
let provider = this.provider;
|
|
||||||
let panel = this.panel;
|
|
||||||
panel.hidden = false;
|
|
||||||
|
|
||||||
// reparent the iframe if we've been customized to a new location
|
|
||||||
if (this.content.parentNode != panel)
|
|
||||||
panel.appendChild(this.content);
|
|
||||||
|
|
||||||
let URLTemplate = provider.markURL;
|
|
||||||
let _dataFn;
|
|
||||||
if (!pageData) {
|
|
||||||
messageManager.addMessageListener("PageMetadata:PageDataResult", _dataFn = (msg) => {
|
|
||||||
messageManager.removeMessageListener("PageMetadata:PageDataResult", _dataFn);
|
|
||||||
this.loadPanel(msg.json, target);
|
|
||||||
});
|
|
||||||
gBrowser.selectedBrowser.messageManager.sendAsyncMessage("PageMetadata:GetPageData", null, { target });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// if this is a share of a selected item, get any microformats
|
|
||||||
if (!pageData.microformats && target) {
|
|
||||||
messageManager.addMessageListener("PageMetadata:MicroformatsResult", _dataFn = (msg) => {
|
|
||||||
messageManager.removeMessageListener("PageMetadata:MicroformatsResult", _dataFn);
|
|
||||||
pageData.microformats = msg.data;
|
|
||||||
this.loadPanel(pageData, target);
|
|
||||||
});
|
|
||||||
gBrowser.selectedBrowser.messageManager.sendAsyncMessage("PageMetadata:GetMicroformats", null, { target });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.pageData = pageData;
|
|
||||||
|
|
||||||
let endpoint = OpenGraphBuilder.generateEndpointURL(URLTemplate, this.pageData);
|
|
||||||
// setup listeners
|
|
||||||
let DOMContentLoaded = (event) => {
|
|
||||||
this._loading = false;
|
|
||||||
this.messageManager.removeMessageListener("DOMContentLoaded", DOMContentLoaded);
|
|
||||||
// add our resizer after the dom is ready
|
|
||||||
if (this._useDynamicResizer) {
|
|
||||||
let DynamicResizeWatcher = Cu.import("resource:///modules/Social.jsm", {}).DynamicResizeWatcher;
|
|
||||||
this._dynamicResizer = new DynamicResizeWatcher();
|
|
||||||
this._dynamicResizer.start(this.panel, this.content);
|
|
||||||
} else if (this._dynamicResizer) {
|
|
||||||
this._dynamicResizer.stop();
|
|
||||||
this._dynamicResizer = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
let contentWindow = this.contentWindow;
|
|
||||||
let markUpdate = function(event) {
|
|
||||||
// update the annotation based on this event, then update the
|
|
||||||
// icon as well
|
|
||||||
this.isMarked = JSON.parse(event.detail).marked;
|
|
||||||
if (this.isMarked) {
|
|
||||||
Social.markURI(provider.origin, gBrowser.currentURI);
|
|
||||||
} else {
|
|
||||||
Social.unmarkURI(provider.origin, gBrowser.currentURI, () => {
|
|
||||||
this.update();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}.bind(this);
|
|
||||||
let unload = () => {
|
|
||||||
contentWindow.removeEventListener("unload", unload);
|
|
||||||
contentWindow.removeEventListener("socialMarkUpdate", markUpdate);
|
|
||||||
}
|
|
||||||
contentWindow.addEventListener("socialMarkUpdate", markUpdate);
|
|
||||||
contentWindow.addEventListener("unload", unload);
|
|
||||||
|
|
||||||
// send the opengraph data
|
|
||||||
this.messageManager.sendAsyncMessage("Social:OpenGraphData", pageData);
|
|
||||||
}
|
|
||||||
this.messageManager.addMessageListener("DOMContentLoaded", DOMContentLoaded);
|
|
||||||
this._loading = true;
|
|
||||||
this.content.setAttribute("src", endpoint);
|
|
||||||
]]></body>
|
|
||||||
</method>
|
|
||||||
|
|
||||||
<method name="openPanel">
|
|
||||||
<parameter name="aResetOnClose"/>
|
|
||||||
<body><![CDATA[
|
|
||||||
let panel = this.panel;
|
|
||||||
let anchor = document.getAnonymousElementByAttribute(this._anchor, "class", "toolbarbutton-icon");
|
|
||||||
// Bug 849216 - open the popup in a setTimeout so we avoid the auto-rollup
|
|
||||||
// handling from preventing it being opened in some cases.
|
|
||||||
setTimeout(() => {
|
|
||||||
panel.openPopup(anchor, "bottomcenter topright", 0, 0, false, false);
|
|
||||||
}, 0);
|
|
||||||
Services.telemetry.getHistogramById("SOCIAL_TOOLBAR_BUTTONS").add(2);
|
|
||||||
]]></body>
|
|
||||||
</method>
|
|
||||||
|
|
||||||
<method name="markCurrentPage">
|
|
||||||
<parameter name="aOpenPanel"/>
|
|
||||||
<body><![CDATA[
|
|
||||||
// we always set the src on click if it has not been set for this tab,
|
|
||||||
// but we only want to open the panel if it was previously annotated.
|
|
||||||
let openPanel = this.isMarked || aOpenPanel;
|
|
||||||
let src = this.content.getAttribute("src");
|
|
||||||
if (!src || src == "about:blank") {
|
|
||||||
this.loadPanel();
|
|
||||||
}
|
|
||||||
if (openPanel)
|
|
||||||
this.openPanel();
|
|
||||||
]]></body>
|
|
||||||
</method>
|
|
||||||
|
|
||||||
<method name="markLink">
|
|
||||||
<parameter name="aUrl"/>
|
|
||||||
<parameter name="aTarget"/>
|
|
||||||
<body><![CDATA[
|
|
||||||
if (!aUrl) {
|
|
||||||
this.markCurrentPage(true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// initiated form an external source, such as gContextMenu, where
|
|
||||||
// pageData is passed into us. In this case, we always load the iframe
|
|
||||||
// and show it since the url may not be the browser tab, but an image,
|
|
||||||
// link, etc. inside the page. We also "update" the iframe to the
|
|
||||||
// previous url when it is closed.
|
|
||||||
this.content.setAttribute("src", "about:blank");
|
|
||||||
this.loadPanel({ url: aUrl }, aTarget);
|
|
||||||
this.openPanel(true);
|
|
||||||
]]></body>
|
|
||||||
</method>
|
|
||||||
|
|
||||||
<method name="dispatchPanelEvent">
|
|
||||||
<parameter name="name"/>
|
|
||||||
<body><![CDATA[
|
|
||||||
let evt = this.contentDocument.createEvent("CustomEvent");
|
|
||||||
evt.initCustomEvent(name, true, true, {});
|
|
||||||
this.contentDocument.documentElement.dispatchEvent(evt);
|
|
||||||
]]></body>
|
|
||||||
</method>
|
|
||||||
|
|
||||||
<method name="onShown">
|
|
||||||
<body><![CDATA[
|
|
||||||
// because the panel may be preloaded, we need to size the panel when
|
|
||||||
// showing as well as after load
|
|
||||||
if (!this._useDynamicResizer) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let sizeSocialPanelToContent = Cu.import("resource:///modules/Social.jsm", {}).sizeSocialPanelToContent;
|
|
||||||
if (!this._loading && this.contentDocument &&
|
|
||||||
this.contentDocument.readyState == "complete") {
|
|
||||||
sizeSocialPanelToContent(this.panel, this.content);
|
|
||||||
} else {
|
|
||||||
let panelBrowserOnload = (message) => {
|
|
||||||
if (message.target != this.content)
|
|
||||||
return;
|
|
||||||
this.messageManager.removeMessageListener("PageVisibility:Show", panelBrowserOnload, true);
|
|
||||||
sizeSocialPanelToContent(this.panel, this.content);
|
|
||||||
};
|
|
||||||
this.messageManager.addMessageListener("PageVisibility:Show", panelBrowserOnload);
|
|
||||||
}
|
|
||||||
]]></body>
|
|
||||||
</method>
|
|
||||||
|
|
||||||
<method name="handleEvent">
|
|
||||||
<parameter name="aEvent"/>
|
|
||||||
<body><![CDATA[
|
|
||||||
if (aEvent.eventPhase != aEvent.BUBBLING_PHASE)
|
|
||||||
return;
|
|
||||||
switch(aEvent.type) {
|
|
||||||
case "DOMLinkAdded": {
|
|
||||||
// much of this logic is from DOMLinkHandler in browser.js, this sets
|
|
||||||
// the presence icon for a chat user, we simply use favicon style
|
|
||||||
// updating
|
|
||||||
let link = aEvent.originalTarget;
|
|
||||||
let rel = link.rel && link.rel.toLowerCase();
|
|
||||||
if (!link || !link.ownerDocument || !rel || !link.href)
|
|
||||||
return;
|
|
||||||
if (link.rel.indexOf("icon") < 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
let ContentLinkHandler = Cu.import("resource:///modules/ContentLinkHandler.jsm", {}).ContentLinkHandler;
|
|
||||||
let uri = ContentLinkHandler.getLinkIconURI(link);
|
|
||||||
if (!uri)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// we cannot size the image when we apply it via listStyleImage, so
|
|
||||||
// use the toolbar image
|
|
||||||
this.setAttribute("image", uri.spec);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "click":
|
|
||||||
Services.telemetry.getHistogramById("SOCIAL_PANEL_CLICKS").add(2);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
]]></body>
|
|
||||||
</method>
|
|
||||||
|
|
||||||
</implementation>
|
|
||||||
<handlers>
|
|
||||||
<handler event="popupshowing"><![CDATA[
|
|
||||||
this._anchor.setAttribute("open", "true");
|
|
||||||
this.content.addEventListener("click", this);
|
|
||||||
]]></handler>
|
|
||||||
<handler event="popupshown"><![CDATA[
|
|
||||||
this.onShown();
|
|
||||||
]]></handler>
|
|
||||||
<handler event="popuphidden"><![CDATA[
|
|
||||||
this._anchor.removeAttribute("open");
|
|
||||||
this.update();
|
|
||||||
this.content.removeEventListener("click", this);
|
|
||||||
]]></handler>
|
|
||||||
<handler event="command"><![CDATA[
|
|
||||||
this.markCurrentPage();
|
|
||||||
]]></handler>
|
|
||||||
</handlers>
|
|
||||||
</binding>
|
|
||||||
|
|
||||||
</bindings>
|
|
|
@ -2,7 +2,6 @@
|
||||||
skip-if = buildapp == "mulet"
|
skip-if = buildapp == "mulet"
|
||||||
support-files =
|
support-files =
|
||||||
blocklist.xml
|
blocklist.xml
|
||||||
checked.jpg
|
|
||||||
head.js
|
head.js
|
||||||
opengraph/og_invalid_url.html
|
opengraph/og_invalid_url.html
|
||||||
opengraph/opengraph.html
|
opengraph/opengraph.html
|
||||||
|
@ -18,12 +17,10 @@ support-files =
|
||||||
social_chat.html
|
social_chat.html
|
||||||
social_crash_content_helper.js
|
social_crash_content_helper.js
|
||||||
social_flyout.html
|
social_flyout.html
|
||||||
social_mark.html
|
|
||||||
social_panel.html
|
social_panel.html
|
||||||
social_postActivation.html
|
social_postActivation.html
|
||||||
social_sidebar.html
|
social_sidebar.html
|
||||||
social_sidebar_empty.html
|
social_sidebar_empty.html
|
||||||
unchecked.jpg
|
|
||||||
!/browser/base/content/test/plugins/blockNoPlugins.xml
|
!/browser/base/content/test/plugins/blockNoPlugins.xml
|
||||||
|
|
||||||
[browser_aboutHome_activation.js]
|
[browser_aboutHome_activation.js]
|
||||||
|
@ -34,15 +31,10 @@ support-files =
|
||||||
[browser_social_chatwindow.js]
|
[browser_social_chatwindow.js]
|
||||||
[browser_social_chatwindow_resize.js]
|
[browser_social_chatwindow_resize.js]
|
||||||
[browser_social_chatwindowfocus.js]
|
[browser_social_chatwindowfocus.js]
|
||||||
skip-if = asan # Bug 1260177
|
|
||||||
[browser_social_contextmenu.js]
|
|
||||||
skip-if = (os == 'linux' && e10s) # Bug 1072669 context menu relies on target element
|
skip-if = (os == 'linux' && e10s) # Bug 1072669 context menu relies on target element
|
||||||
[browser_social_errorPage.js]
|
[browser_social_errorPage.js]
|
||||||
[browser_social_flyout.js]
|
[browser_social_flyout.js]
|
||||||
[browser_social_isVisible.js]
|
[browser_social_isVisible.js]
|
||||||
[browser_social_marks.js]
|
|
||||||
[browser_social_marks_context.js]
|
|
||||||
[browser_social_multiprovider.js]
|
[browser_social_multiprovider.js]
|
||||||
[browser_social_sidebar.js]
|
[browser_social_sidebar.js]
|
||||||
[browser_social_status.js]
|
|
||||||
[browser_social_window.js]
|
[browser_social_window.js]
|
||||||
|
|
|
@ -1,74 +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://gre/modules/SocialService.jsm", {}).SocialService;
|
|
||||||
|
|
||||||
var manifest = { // used for testing install
|
|
||||||
name: "provider test1",
|
|
||||||
origin: "https://test1.example.com",
|
|
||||||
markURL: "https://test1.example.com/browser/browser/base/content/test/social/social_mark.html?url=%{url}",
|
|
||||||
markedIcon: "https://test1.example.com/browser/browser/base/content/test/social/unchecked.jpg",
|
|
||||||
unmarkedIcon: "https://test1.example.com/browser/browser/base/content/test/social/checked.jpg",
|
|
||||||
|
|
||||||
iconURL: "https://test1.example.com/browser/browser/base/content/test/general/moz.png",
|
|
||||||
version: "1.0"
|
|
||||||
};
|
|
||||||
|
|
||||||
function test() {
|
|
||||||
waitForExplicitFinish();
|
|
||||||
let frameScript = "data:,(" + function frame_script() {
|
|
||||||
addEventListener("OpenGraphData", function (aEvent) {
|
|
||||||
sendAsyncMessage("sharedata", aEvent.detail);
|
|
||||||
}, true, true);
|
|
||||||
}.toString() + ")();";
|
|
||||||
let mm = getGroupMessageManager("social");
|
|
||||||
mm.loadFrameScript(frameScript, true);
|
|
||||||
|
|
||||||
runSocialTestWithProvider(manifest, function (finishcb) {
|
|
||||||
runSocialTests(tests, undefined, undefined, function () {
|
|
||||||
mm.removeDelayedFrameScript(frameScript);
|
|
||||||
finishcb();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
var tests = {
|
|
||||||
testMarkMicroformats: function(next) {
|
|
||||||
// emulates context menu action using target element, calling SocialMarks.markLink
|
|
||||||
let provider = Social._getProviderFromOrigin(manifest.origin);
|
|
||||||
let target, testTab;
|
|
||||||
|
|
||||||
// browser_share tests microformats on the full page, this is testing a
|
|
||||||
// specific target element.
|
|
||||||
let expecting = JSON.stringify({
|
|
||||||
"url": "https://example.com/browser/browser/base/content/test/social/microformats.html",
|
|
||||||
"microformats": {
|
|
||||||
"items": [{
|
|
||||||
"type": ["h-review"],
|
|
||||||
"properties": {
|
|
||||||
"rating": ["4.5"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"rels": {},
|
|
||||||
"rel-urls": {}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let mm = getGroupMessageManager("social");
|
|
||||||
mm.addMessageListener("sharedata", function handler(msg) {
|
|
||||||
is(msg.data, expecting, "microformats data ok");
|
|
||||||
mm.removeMessageListener("sharedata", handler);
|
|
||||||
BrowserTestUtils.removeTab(testTab).then(next);
|
|
||||||
});
|
|
||||||
|
|
||||||
let url = "https://example.com/browser/browser/base/content/test/social/microformats.html"
|
|
||||||
BrowserTestUtils.openNewForegroundTab(gBrowser, url).then(tab => {
|
|
||||||
testTab = tab;
|
|
||||||
let doc = tab.linkedBrowser.contentDocument;
|
|
||||||
target = doc.getElementById("test-review");
|
|
||||||
SocialMarks.markLink(manifest.origin, url, target);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,232 +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://gre/modules/SocialService.jsm", {}).SocialService;
|
|
||||||
|
|
||||||
var manifest2 = { // used for testing install
|
|
||||||
name: "provider test1",
|
|
||||||
origin: "https://test1.example.com",
|
|
||||||
markURL: "https://test1.example.com/browser/browser/base/content/test/social/social_mark.html?url=%{url}",
|
|
||||||
markedIcon: "https://test1.example.com/browser/browser/base/content/test/social/unchecked.jpg",
|
|
||||||
unmarkedIcon: "https://test1.example.com/browser/browser/base/content/test/social/checked.jpg",
|
|
||||||
|
|
||||||
iconURL: "https://test1.example.com/browser/browser/base/content/test/general/moz.png",
|
|
||||||
version: "1.0"
|
|
||||||
};
|
|
||||||
var manifest3 = { // used for testing install
|
|
||||||
name: "provider test2",
|
|
||||||
origin: "https://test2.example.com",
|
|
||||||
sidebarURL: "https://test2.example.com/browser/browser/base/content/test/social/social_sidebar.html",
|
|
||||||
iconURL: "https://test2.example.com/browser/browser/base/content/test/general/moz.png",
|
|
||||||
version: "1.0"
|
|
||||||
};
|
|
||||||
|
|
||||||
function test() {
|
|
||||||
waitForExplicitFinish();
|
|
||||||
|
|
||||||
let frameScript = "data:,(" + function frame_script() {
|
|
||||||
addEventListener("visibilitychange", function() {
|
|
||||||
sendAsyncMessage("visibility", content.document.hidden ? "hidden" : "shown");
|
|
||||||
});
|
|
||||||
}.toString() + ")();";
|
|
||||||
let mm = getGroupMessageManager("social");
|
|
||||||
mm.loadFrameScript(frameScript, true);
|
|
||||||
|
|
||||||
PopupNotifications.panel.setAttribute("animate", "false");
|
|
||||||
registerCleanupFunction(function () {
|
|
||||||
PopupNotifications.panel.removeAttribute("animate");
|
|
||||||
mm.removeDelayedFrameScript(frameScript);
|
|
||||||
});
|
|
||||||
|
|
||||||
runSocialTests(tests, undefined, undefined, finish);
|
|
||||||
}
|
|
||||||
|
|
||||||
var tests = {
|
|
||||||
testButtonDisabledOnActivate: function(next) {
|
|
||||||
// starting on about:blank page, share should be visible but disabled when
|
|
||||||
// adding provider
|
|
||||||
is(gBrowser.selectedBrowser.currentURI.spec, "about:blank");
|
|
||||||
SocialService.addProvider(manifest2, function(provider) {
|
|
||||||
is(provider.origin, manifest2.origin, "provider is installed");
|
|
||||||
let id = SocialMarks._toolbarHelper.idFromOrigin(manifest2.origin);
|
|
||||||
let widget = CustomizableUI.getWidget(id).forWindow(window)
|
|
||||||
ok(widget.node, "button added to widget set");
|
|
||||||
|
|
||||||
// bypass widget go directly to dom, check attribute states
|
|
||||||
let button = document.getElementById(id);
|
|
||||||
is(button.disabled, true, "mark button is disabled");
|
|
||||||
// verify the attribute for proper css
|
|
||||||
is(button.getAttribute("disabled"), "true", "mark button attribute is disabled");
|
|
||||||
// button should be visible
|
|
||||||
is(button.hidden, false, "mark button is visible");
|
|
||||||
|
|
||||||
checkSocialUI(window);
|
|
||||||
SocialService.disableProvider(manifest2.origin, next);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
testNoButtonOnEnable: function(next) {
|
|
||||||
// we expect the addon install dialog to appear, we need to accept the
|
|
||||||
// install from the dialog.
|
|
||||||
let panel = document.getElementById("servicesInstall-notification");
|
|
||||||
BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown").then(() => {
|
|
||||||
info("servicesInstall-notification panel opened");
|
|
||||||
panel.button.click();
|
|
||||||
});
|
|
||||||
|
|
||||||
let activationURL = manifest3.origin + "/browser/browser/base/content/test/social/social_activate.html"
|
|
||||||
BrowserTestUtils.openNewForegroundTab(gBrowser, activationURL).then(tab => {
|
|
||||||
let doc = tab.linkedBrowser.contentDocument;
|
|
||||||
let data = {
|
|
||||||
origin: doc.nodePrincipal.origin,
|
|
||||||
url: doc.location.href,
|
|
||||||
manifest: manifest3,
|
|
||||||
window: window
|
|
||||||
}
|
|
||||||
|
|
||||||
Social.installProvider(data, function(addonManifest) {
|
|
||||||
// enable the provider so we know the button would have appeared
|
|
||||||
SocialService.enableProvider(manifest3.origin, function(provider) {
|
|
||||||
is(provider.origin, manifest3.origin, "provider is installed");
|
|
||||||
let id = SocialMarks._toolbarHelper.idFromOrigin(provider.origin);
|
|
||||||
let widget = CustomizableUI.getWidget(id);
|
|
||||||
ok(!widget || !widget.forWindow(window).node, "no button added to widget set");
|
|
||||||
Social.uninstallProvider(manifest3.origin, function() {
|
|
||||||
BrowserTestUtils.removeTab(tab).then(next);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
testButtonOnEnable: function(next) {
|
|
||||||
let panel = document.getElementById("servicesInstall-notification");
|
|
||||||
BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown").then(() => {
|
|
||||||
info("servicesInstall-notification panel opened");
|
|
||||||
panel.button.click();
|
|
||||||
});
|
|
||||||
|
|
||||||
// enable the provider now
|
|
||||||
let activationURL = manifest2.origin + "/browser/browser/base/content/test/social/social_activate.html"
|
|
||||||
BrowserTestUtils.openNewForegroundTab(gBrowser, activationURL).then(tab => {
|
|
||||||
let doc = tab.linkedBrowser.contentDocument;
|
|
||||||
let data = {
|
|
||||||
origin: doc.nodePrincipal.origin,
|
|
||||||
url: doc.location.href,
|
|
||||||
manifest: manifest2,
|
|
||||||
window: window
|
|
||||||
}
|
|
||||||
|
|
||||||
Social.installProvider(data, function(addonManifest) {
|
|
||||||
SocialService.enableProvider(manifest2.origin, function(provider) {
|
|
||||||
is(provider.origin, manifest2.origin, "provider is installed");
|
|
||||||
let id = SocialMarks._toolbarHelper.idFromOrigin(manifest2.origin);
|
|
||||||
let widget = CustomizableUI.getWidget(id).forWindow(window)
|
|
||||||
ok(widget.node, "button added to widget set");
|
|
||||||
|
|
||||||
// bypass widget go directly to dom, check attribute states
|
|
||||||
let button = document.getElementById(id);
|
|
||||||
is(button.disabled, false, "mark button is disabled");
|
|
||||||
// verify the attribute for proper css
|
|
||||||
ok(!button.hasAttribute("disabled"), "mark button attribute is disabled");
|
|
||||||
// button should be visible
|
|
||||||
is(button.hidden, false, "mark button is visible");
|
|
||||||
|
|
||||||
checkSocialUI(window);
|
|
||||||
BrowserTestUtils.removeTab(tab).then(next);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
testMarkPanel: function(next) {
|
|
||||||
// click on panel to open and wait for visibility
|
|
||||||
let provider = Social._getProviderFromOrigin(manifest2.origin);
|
|
||||||
ok(provider.enabled, "provider is enabled");
|
|
||||||
let id = SocialMarks._toolbarHelper.idFromOrigin(manifest2.origin);
|
|
||||||
let widget = CustomizableUI.getWidget(id);
|
|
||||||
let btn = widget.forWindow(window).node;
|
|
||||||
ok(btn, "got a mark button");
|
|
||||||
let ourTab;
|
|
||||||
|
|
||||||
BrowserTestUtils.waitForEvent(btn.panel, "popupshown").then(() => {
|
|
||||||
info("marks panel shown");
|
|
||||||
let doc = btn.contentDocument;
|
|
||||||
let unmarkBtn = doc.getElementById("unmark");
|
|
||||||
ok(unmarkBtn, "testMarkPanel - got the panel unmark button");
|
|
||||||
EventUtils.sendMouseEvent({type: "click"}, unmarkBtn, btn.contentWindow);
|
|
||||||
});
|
|
||||||
|
|
||||||
BrowserTestUtils.waitForEvent(btn.panel, "popuphidden").then(() => {
|
|
||||||
BrowserTestUtils.removeTab(ourTab).then(() => {
|
|
||||||
ok(btn.disabled, "button is disabled");
|
|
||||||
next();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// verify markbutton is disabled when there is no browser url
|
|
||||||
ok(btn.disabled, "button is disabled");
|
|
||||||
let activationURL = manifest2.origin + "/browser/browser/base/content/test/social/social_activate.html"
|
|
||||||
BrowserTestUtils.openNewForegroundTab(gBrowser, activationURL).then(tab => {
|
|
||||||
ourTab = tab;
|
|
||||||
ok(!btn.disabled, "button is enabled");
|
|
||||||
// first click marks the page, second click opens the page. We have to
|
|
||||||
// synthesize so the command event happens
|
|
||||||
EventUtils.synthesizeMouseAtCenter(btn, {});
|
|
||||||
// wait for the button to be marked, click to open panel
|
|
||||||
is(btn.panel.state, "closed", "panel should not be visible yet");
|
|
||||||
BrowserTestUtils.waitForCondition(() => btn.isMarked, "button is marked").then(() => {
|
|
||||||
EventUtils.synthesizeMouseAtCenter(btn, {});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
testMarkPanelOffline: function(next) {
|
|
||||||
// click on panel to open and wait for visibility
|
|
||||||
let provider = Social._getProviderFromOrigin(manifest2.origin);
|
|
||||||
ok(provider.enabled, "provider is enabled");
|
|
||||||
let id = SocialMarks._toolbarHelper.idFromOrigin(manifest2.origin);
|
|
||||||
let widget = CustomizableUI.getWidget(id);
|
|
||||||
let btn = widget.forWindow(window).node;
|
|
||||||
ok(btn, "got a mark button");
|
|
||||||
|
|
||||||
// verify markbutton is disabled when there is no browser url
|
|
||||||
ok(btn.disabled, "button is disabled");
|
|
||||||
let activationURL = manifest2.origin + "/browser/browser/base/content/test/social/social_activate.html";
|
|
||||||
BrowserTestUtils.openNewForegroundTab(gBrowser, activationURL).then(tab => {
|
|
||||||
ok(!btn.disabled, "button is enabled");
|
|
||||||
goOffline().then(function() {
|
|
||||||
info("testing offline error page");
|
|
||||||
// wait for popupshown
|
|
||||||
BrowserTestUtils.waitForEvent(btn.panel, "popupshown").then(() => {
|
|
||||||
info("marks panel is open");
|
|
||||||
ensureFrameLoaded(btn.content).then(() => {
|
|
||||||
is(btn.contentDocument.documentURI.indexOf("about:socialerror?mode=tryAgainOnly"), 0, "social error page is showing "+btn.contentDocument.documentURI);
|
|
||||||
// cleanup after the page has been unmarked
|
|
||||||
BrowserTestUtils.removeTab(tab).then(() => {
|
|
||||||
ok(btn.disabled, "button is disabled");
|
|
||||||
goOnline().then(next);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
btn.markCurrentPage();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
testButtonOnDisable: function(next) {
|
|
||||||
// enable the provider now
|
|
||||||
let provider = Social._getProviderFromOrigin(manifest2.origin);
|
|
||||||
ok(provider, "provider is installed");
|
|
||||||
SocialService.disableProvider(manifest2.origin, function() {
|
|
||||||
let id = SocialMarks._toolbarHelper.idFromOrigin(manifest2.origin);
|
|
||||||
BrowserTestUtils.waitForCondition(() => {
|
|
||||||
// getWidget now returns null since we've destroyed the widget
|
|
||||||
return !CustomizableUI.getWidget(id)
|
|
||||||
}, "button does not exist after disabling the provider").then(() => {
|
|
||||||
checkSocialUI(window);
|
|
||||||
Social.uninstallProvider(manifest2.origin, next);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,106 +0,0 @@
|
||||||
var SocialService = Cu.import("resource://gre/modules/SocialService.jsm", {}).SocialService;
|
|
||||||
|
|
||||||
function makeMarkProvider(origin) {
|
|
||||||
return { // used for testing install
|
|
||||||
name: "mark provider " + origin,
|
|
||||||
origin: "https://" + origin + ".example.com",
|
|
||||||
markURL: "https://" + origin + ".example.com/browser/browser/base/content/test/social/social_mark.html?url=%{url}",
|
|
||||||
markedIcon: "https://" + origin + ".example.com/browser/browser/base/content/test/social/unchecked.jpg",
|
|
||||||
unmarkedIcon: "https://" + origin + ".example.com/browser/browser/base/content/test/social/checked.jpg",
|
|
||||||
iconURL: "https://" + origin + ".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");
|
|
||||||
});
|
|
||||||
|
|
||||||
runSocialTests(tests, undefined, undefined, finish);
|
|
||||||
}
|
|
||||||
|
|
||||||
var tests = {
|
|
||||||
testContextSubmenu: function(next) {
|
|
||||||
// install 4 providers to test that the menu's are added as submenus
|
|
||||||
let manifests = [
|
|
||||||
makeMarkProvider("sub1.test1"),
|
|
||||||
makeMarkProvider("sub2.test1"),
|
|
||||||
makeMarkProvider("sub1.test2"),
|
|
||||||
makeMarkProvider("sub2.test2")
|
|
||||||
];
|
|
||||||
let installed = [];
|
|
||||||
let markLinkMenu = document.getElementById("context-marklinkMenu").firstChild;
|
|
||||||
let markPageMenu = document.getElementById("context-markpageMenu").firstChild;
|
|
||||||
|
|
||||||
function addProviders(callback) {
|
|
||||||
let manifest = manifests.pop();
|
|
||||||
if (!manifest) {
|
|
||||||
info("INSTALLATION FINISHED");
|
|
||||||
executeSoon(callback);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
info("INSTALLING " + manifest.origin);
|
|
||||||
let panel = document.getElementById("servicesInstall-notification");
|
|
||||||
BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown").then(() => {
|
|
||||||
info("servicesInstall-notification panel opened");
|
|
||||||
panel.button.click();
|
|
||||||
});
|
|
||||||
|
|
||||||
let activationURL = manifest.origin + "/browser/browser/base/content/test/social/social_activate.html"
|
|
||||||
let id = SocialMarks._toolbarHelper.idFromOrigin(manifest.origin);
|
|
||||||
let toolbar = document.getElementById("nav-bar");
|
|
||||||
BrowserTestUtils.openNewForegroundTab(gBrowser, activationURL).then(tab => {
|
|
||||||
let doc = tab.linkedBrowser.contentDocument;
|
|
||||||
let data = {
|
|
||||||
origin: doc.nodePrincipal.origin,
|
|
||||||
url: doc.location.href,
|
|
||||||
manifest: manifest,
|
|
||||||
window: window
|
|
||||||
}
|
|
||||||
|
|
||||||
Social.installProvider(data, function(addonManifest) {
|
|
||||||
// enable the provider so we know the button would have appeared
|
|
||||||
SocialService.enableProvider(manifest.origin, function(provider) {
|
|
||||||
BrowserTestUtils.waitForCondition(() => { return CustomizableUI.getWidget(id) },
|
|
||||||
"button exists after enabling social").then(() => {
|
|
||||||
BrowserTestUtils.removeTab(tab).then(() => {
|
|
||||||
installed.push(manifest.origin);
|
|
||||||
// checkSocialUI will properly check where the menus are located
|
|
||||||
checkSocialUI(window);
|
|
||||||
executeSoon(function() {
|
|
||||||
addProviders(callback);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function removeProviders(callback) {
|
|
||||||
let origin = installed.pop();
|
|
||||||
if (!origin) {
|
|
||||||
executeSoon(callback);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Social.uninstallProvider(origin, function(provider) {
|
|
||||||
executeSoon(function() {
|
|
||||||
removeProviders(callback);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
addProviders(function() {
|
|
||||||
removeProviders(function() {
|
|
||||||
is(SocialMarks.getProviders().length, 0, "mark providers removed");
|
|
||||||
is(markLinkMenu.childNodes.length, 0, "marklink menu ok");
|
|
||||||
is(markPageMenu.childNodes.length, 0, "markpage menu ok");
|
|
||||||
checkSocialUI(window);
|
|
||||||
next();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,216 +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://gre/modules/SocialService.jsm", {}).SocialService;
|
|
||||||
|
|
||||||
var manifest = { // builtin provider
|
|
||||||
name: "provider example.com",
|
|
||||||
origin: "https://example.com",
|
|
||||||
sidebarURL: "https://example.com/browser/browser/base/content/test/social/social_sidebar.html",
|
|
||||||
iconURL: "https://example.com/browser/browser/base/content/test/general/moz.png"
|
|
||||||
};
|
|
||||||
var manifest2 = { // used for testing install
|
|
||||||
name: "provider test1",
|
|
||||||
origin: "https://test1.example.com",
|
|
||||||
statusURL: "https://test1.example.com/browser/browser/base/content/test/social/social_panel.html",
|
|
||||||
iconURL: "https://test1.example.com/browser/browser/base/content/test/general/moz.png",
|
|
||||||
version: "1.0"
|
|
||||||
};
|
|
||||||
var manifest3 = { // used for testing install
|
|
||||||
name: "provider test2",
|
|
||||||
origin: "https://test2.example.com",
|
|
||||||
sidebarURL: "https://test2.example.com/browser/browser/base/content/test/social/social_sidebar.html",
|
|
||||||
iconURL: "https://test2.example.com/browser/browser/base/content/test/general/moz.png",
|
|
||||||
version: "1.0"
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
function openWindowAndWaitForInit(callback) {
|
|
||||||
let topic = "browser-delayed-startup-finished";
|
|
||||||
let w = OpenBrowserWindow();
|
|
||||||
Services.obs.addObserver(function providerSet(subject, topic, data) {
|
|
||||||
Services.obs.removeObserver(providerSet, topic);
|
|
||||||
executeSoon(() => callback(w));
|
|
||||||
}, topic, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
function test() {
|
|
||||||
waitForExplicitFinish();
|
|
||||||
|
|
||||||
let frameScript = "data:,(" + function frame_script() {
|
|
||||||
addMessageListener("socialTest-sendEvent", function(msg) {
|
|
||||||
let data = msg.data;
|
|
||||||
let evt = content.document.createEvent("CustomEvent");
|
|
||||||
evt.initCustomEvent(data.name, true, true, JSON.stringify(data.data));
|
|
||||||
content.document.documentElement.dispatchEvent(evt);
|
|
||||||
});
|
|
||||||
}.toString() + ")();";
|
|
||||||
let mm = getGroupMessageManager("social");
|
|
||||||
mm.loadFrameScript(frameScript, true);
|
|
||||||
|
|
||||||
PopupNotifications.panel.setAttribute("animate", "false");
|
|
||||||
registerCleanupFunction(function () {
|
|
||||||
PopupNotifications.panel.removeAttribute("animate");
|
|
||||||
mm.removeDelayedFrameScript(frameScript);
|
|
||||||
});
|
|
||||||
|
|
||||||
runSocialTestWithProvider(manifest, function (finishcb) {
|
|
||||||
runSocialTests(tests, undefined, undefined, function () {
|
|
||||||
Services.prefs.clearUserPref("social.remote-install.enabled");
|
|
||||||
// just in case the tests failed, clear these here as well
|
|
||||||
Services.prefs.clearUserPref("social.whitelist");
|
|
||||||
CustomizableUI.reset();
|
|
||||||
finishcb();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
var tests = {
|
|
||||||
testNoButtonOnEnable: function(next) {
|
|
||||||
// we expect the addon install dialog to appear, we need to accept the
|
|
||||||
// install from the dialog.
|
|
||||||
let panel = document.getElementById("servicesInstall-notification");
|
|
||||||
BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown").then(() => {
|
|
||||||
info("servicesInstall-notification panel opened");
|
|
||||||
panel.button.click();
|
|
||||||
})
|
|
||||||
|
|
||||||
let activationURL = manifest3.origin + "/browser/browser/base/content/test/social/social_activate.html"
|
|
||||||
BrowserTestUtils.openNewForegroundTab(gBrowser, activationURL).then(tab => {
|
|
||||||
let doc = tab.linkedBrowser.contentDocument;
|
|
||||||
let data = {
|
|
||||||
origin: doc.nodePrincipal.origin,
|
|
||||||
url: doc.location.href,
|
|
||||||
manifest: manifest3,
|
|
||||||
window: window
|
|
||||||
}
|
|
||||||
Social.installProvider(data, function(addonManifest) {
|
|
||||||
// enable the provider so we know the button would have appeared
|
|
||||||
SocialService.enableProvider(manifest3.origin, function(provider) {
|
|
||||||
is(provider.origin, manifest3.origin, "provider is installed");
|
|
||||||
let id = SocialStatus._toolbarHelper.idFromOrigin(provider.origin);
|
|
||||||
let widget = CustomizableUI.getWidget(id);
|
|
||||||
ok(!widget || !widget.forWindow(window).node, "no button added to widget set");
|
|
||||||
Social.uninstallProvider(manifest3.origin, function() {
|
|
||||||
BrowserTestUtils.removeTab(tab).then(next);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
testButtonOnEnable: function(next) {
|
|
||||||
let panel = document.getElementById("servicesInstall-notification");
|
|
||||||
BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown").then(() => {
|
|
||||||
info("servicesInstall-notification panel opened");
|
|
||||||
panel.button.click();
|
|
||||||
});
|
|
||||||
|
|
||||||
// enable the provider now
|
|
||||||
let activationURL = manifest2.origin + "/browser/browser/base/content/test/social/social_activate.html"
|
|
||||||
BrowserTestUtils.openNewForegroundTab(gBrowser, activationURL).then(tab => {
|
|
||||||
let doc = tab.linkedBrowser.contentDocument;
|
|
||||||
let data = {
|
|
||||||
origin: doc.nodePrincipal.origin,
|
|
||||||
url: doc.location.href,
|
|
||||||
manifest: manifest2,
|
|
||||||
window: window
|
|
||||||
}
|
|
||||||
|
|
||||||
Social.installProvider(data, function(addonManifest) {
|
|
||||||
SocialService.enableProvider(manifest2.origin, function(provider) {
|
|
||||||
is(provider.origin, manifest2.origin, "provider is installed");
|
|
||||||
let id = SocialStatus._toolbarHelper.idFromOrigin(manifest2.origin);
|
|
||||||
let widget = CustomizableUI.getWidget(id).forWindow(window);
|
|
||||||
ok(widget.node, "button added to widget set");
|
|
||||||
checkSocialUI(window);
|
|
||||||
BrowserTestUtils.removeTab(tab).then(next);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
testStatusPanel: function(next) {
|
|
||||||
let icon = {
|
|
||||||
name: "testIcon",
|
|
||||||
iconURL: "chrome://browser/skin/Info.png",
|
|
||||||
counter: 1
|
|
||||||
};
|
|
||||||
|
|
||||||
// click on panel to open and wait for visibility
|
|
||||||
let provider = Social._getProviderFromOrigin(manifest2.origin);
|
|
||||||
let id = SocialStatus._toolbarHelper.idFromOrigin(manifest2.origin);
|
|
||||||
let widget = CustomizableUI.getWidget(id);
|
|
||||||
let btn = widget.forWindow(window).node;
|
|
||||||
|
|
||||||
// Disable the transition
|
|
||||||
let panel = document.getElementById("social-notification-panel");
|
|
||||||
panel.setAttribute("animate", "false");
|
|
||||||
BrowserTestUtils.waitForEvent(panel, "popupshown").then(() => {
|
|
||||||
ensureFrameLoaded(panel.firstChild).then(() => {
|
|
||||||
let mm = panel.firstChild.messageManager;
|
|
||||||
mm.sendAsyncMessage("socialTest-sendEvent", { name: "Social:Notification", data: icon });
|
|
||||||
BrowserTestUtils.waitForCondition(
|
|
||||||
() => { return btn.getAttribute("badge"); }, "button updated by notification").then(() => {
|
|
||||||
is(btn.style.listStyleImage, "url(\"" + icon.iconURL + "\")", "notification icon updated");
|
|
||||||
panel.hidePopup();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
BrowserTestUtils.waitForEvent(panel, "popuphidden").then(() => {
|
|
||||||
panel.removeAttribute("animate");
|
|
||||||
next();
|
|
||||||
});
|
|
||||||
btn.click(); // open the panel
|
|
||||||
},
|
|
||||||
|
|
||||||
testPanelOffline: function(next) {
|
|
||||||
// click on panel to open and wait for visibility
|
|
||||||
let provider = Social._getProviderFromOrigin(manifest2.origin);
|
|
||||||
ok(provider.enabled, "provider is enabled");
|
|
||||||
let id = SocialStatus._toolbarHelper.idFromOrigin(manifest2.origin);
|
|
||||||
let widget = CustomizableUI.getWidget(id);
|
|
||||||
let btn = widget.forWindow(window).node;
|
|
||||||
ok(btn, "got a status button");
|
|
||||||
let frameId = btn.getAttribute("notificationFrameId");
|
|
||||||
let frame = document.getElementById(frameId);
|
|
||||||
|
|
||||||
goOffline().then(function() {
|
|
||||||
info("testing offline error page");
|
|
||||||
// wait for popupshown
|
|
||||||
let panel = document.getElementById("social-notification-panel");
|
|
||||||
BrowserTestUtils.waitForEvent(panel, "popupshown").then(() => {
|
|
||||||
ensureFrameLoaded(frame).then(() => {
|
|
||||||
is(frame.contentDocument.documentURI.indexOf("about:socialerror?mode=tryAgainOnly"), 0, "social error page is showing "+frame.contentDocument.documentURI);
|
|
||||||
// We got our error page, reset to avoid test leak.
|
|
||||||
BrowserTestUtils.waitForEvent(frame, "load", true).then(() => {
|
|
||||||
is(frame.contentDocument.documentURI, "about:blank", "closing error panel");
|
|
||||||
BrowserTestUtils.waitForEvent(panel, "popuphidden").then(next);
|
|
||||||
panel.hidePopup();
|
|
||||||
});
|
|
||||||
goOnline().then(() => {
|
|
||||||
info("resetting error panel");
|
|
||||||
frame.setAttribute("src", "about:blank");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
// reload after going offline, wait for unload to open panel
|
|
||||||
BrowserTestUtils.waitForEvent(frame, "unload", true).then(() => {
|
|
||||||
btn.click();
|
|
||||||
});
|
|
||||||
frame.contentDocument.location.reload();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
testButtonOnDisable: function(next) {
|
|
||||||
// enable the provider now
|
|
||||||
let provider = Social._getProviderFromOrigin(manifest2.origin);
|
|
||||||
ok(provider, "provider is installed");
|
|
||||||
SocialService.disableProvider(manifest2.origin, function() {
|
|
||||||
let id = SocialStatus._toolbarHelper.idFromOrigin(manifest2.origin);
|
|
||||||
BrowserTestUtils.waitForCondition(() => { return !document.getElementById(id) },
|
|
||||||
"button does not exist after disabling the provider").then(() => {
|
|
||||||
Social.uninstallProvider(manifest2.origin, next);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
Двоичные данные
browser/base/content/test/social/checked.jpg
Двоичные данные
browser/base/content/test/social/checked.jpg
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 785 B |
|
@ -66,7 +66,7 @@ function runSocialTestWithProvider(manifest, callback, finishcallback) {
|
||||||
SessionStore.setWindowValue(window, "socialSidebar", "");
|
SessionStore.setWindowValue(window, "socialSidebar", "");
|
||||||
for (let i = 0; i < manifests.length; i++) {
|
for (let i = 0; i < manifests.length; i++) {
|
||||||
let m = manifests[i];
|
let m = manifests[i];
|
||||||
for (let what of ['sidebarURL', 'iconURL', 'shareURL', 'markURL']) {
|
for (let what of ['sidebarURL', 'iconURL', 'shareURL']) {
|
||||||
if (m[what]) {
|
if (m[what]) {
|
||||||
yield promiseSocialUrlNotRemembered(m[what]);
|
yield promiseSocialUrlNotRemembered(m[what]);
|
||||||
}
|
}
|
||||||
|
@ -232,42 +232,6 @@ function checkSocialUI(win) {
|
||||||
}
|
}
|
||||||
isbool(win.SocialSidebar.canShow, sidebarEnabled, "social sidebar active?");
|
isbool(win.SocialSidebar.canShow, sidebarEnabled, "social sidebar active?");
|
||||||
|
|
||||||
let contextMenus = [
|
|
||||||
{
|
|
||||||
type: "link",
|
|
||||||
id: "context-marklinkMenu",
|
|
||||||
label: "social.marklinkMenu.label"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: "page",
|
|
||||||
id: "context-markpageMenu",
|
|
||||||
label: "social.markpageMenu.label"
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
for (let c of contextMenus) {
|
|
||||||
let leMenu = document.getElementById(c.id);
|
|
||||||
let parent, menus;
|
|
||||||
let markProviders = SocialMarks.getProviders();
|
|
||||||
if (markProviders.length > SocialMarks.MENU_LIMIT) {
|
|
||||||
// menus should be in a submenu, not in the top level of the context menu
|
|
||||||
parent = leMenu.firstChild;
|
|
||||||
menus = document.getElementsByClassName("context-mark" + c.type);
|
|
||||||
_is(menus.length, 0, "menu's are not in main context menu\n");
|
|
||||||
menus = parent.childNodes;
|
|
||||||
_is(menus.length, markProviders.length, c.id + " menu exists for each mark provider");
|
|
||||||
} else {
|
|
||||||
// menus should be in the top level of the context menu, not in a submenu
|
|
||||||
parent = leMenu.parentNode;
|
|
||||||
menus = document.getElementsByClassName("context-mark" + c.type);
|
|
||||||
_is(menus.length, markProviders.length, c.id + " menu exists for each mark provider");
|
|
||||||
menus = leMenu.firstChild.childNodes;
|
|
||||||
_is(menus.length, 0, "menu's are not in context submenu\n");
|
|
||||||
}
|
|
||||||
for (let m of menus)
|
|
||||||
_is(m.parentNode, parent, "menu has correct parent");
|
|
||||||
}
|
|
||||||
|
|
||||||
// and for good measure, check all the social commands.
|
// and for good measure, check all the social commands.
|
||||||
isbool(!doc.getElementById("Social:ToggleSidebar").hidden, sidebarEnabled, "Social:ToggleSidebar visible?");
|
isbool(!doc.getElementById("Social:ToggleSidebar").hidden, sidebarEnabled, "Social:ToggleSidebar visible?");
|
||||||
isbool(!doc.getElementById("Social:ToggleNotifications").hidden, enabled, "Social:ToggleNotifications visible?");
|
isbool(!doc.getElementById("Social:ToggleNotifications").hidden, enabled, "Social:ToggleNotifications visible?");
|
||||||
|
|
|
@ -14,7 +14,6 @@ var data = {
|
||||||
|
|
||||||
// at least one of these must be defined
|
// at least one of these must be defined
|
||||||
"sidebarURL": "/browser/browser/base/content/test/social/social_sidebar.html",
|
"sidebarURL": "/browser/browser/base/content/test/social/social_sidebar.html",
|
||||||
"statusURL": "/browser/browser/base/content/test/social/social_panel.html",
|
|
||||||
"postActivationURL": "/browser/browser/base/content/test/social/social_postActivation.html",
|
"postActivationURL": "/browser/browser/base/content/test/social/social_postActivation.html",
|
||||||
|
|
||||||
// should be available for display purposes
|
// should be available for display purposes
|
||||||
|
|
|
@ -1,41 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<link id="siteicon" rel="icon" href="./icon.png"/>
|
|
||||||
<title>Demo Mark Window</title>
|
|
||||||
<script type="text/javascript">
|
|
||||||
|
|
||||||
function updateTextNode(parent, text) {
|
|
||||||
var textNode = parent.childNodes[0];
|
|
||||||
if (textNode)
|
|
||||||
parent.removeChild(textNode);
|
|
||||||
textNode = document.createTextNode(text);
|
|
||||||
parent.appendChild(textNode);
|
|
||||||
}
|
|
||||||
function onLoad() {
|
|
||||||
updateTextNode(document.getElementById("shared"), location.search);
|
|
||||||
socialMarkUpdate(true);
|
|
||||||
}
|
|
||||||
function socialMarkUpdate(isMarked) {
|
|
||||||
var evt = document.createEvent("CustomEvent");
|
|
||||||
evt.initCustomEvent("socialMarkUpdate", true, true, JSON.stringify({marked: isMarked}));
|
|
||||||
document.documentElement.dispatchEvent(evt);
|
|
||||||
}
|
|
||||||
var shareData;
|
|
||||||
addEventListener("OpenGraphData", function(e) {
|
|
||||||
shareData = JSON.parse(e.detail);
|
|
||||||
updateTextNode(document.getElementById("shared"), shareData.url);
|
|
||||||
socialMarkUpdate(true);
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body onload="onLoad()">
|
|
||||||
<div id="content">
|
|
||||||
<h3>This window shows the mark data</h3>
|
|
||||||
<div>Page Marked: <div id="shared" class="textbox"></div></div>
|
|
||||||
<button id="unmark" onclick="socialMarkUpdate(false); window.close()">Unmark</button>
|
|
||||||
<button onclick="window.close();">Close</button>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
Двоичные данные
browser/base/content/test/social/unchecked.jpg
Двоичные данные
browser/base/content/test/social/unchecked.jpg
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 779 B |
|
@ -189,7 +189,6 @@ browser.jar:
|
||||||
#ifdef XP_WIN
|
#ifdef XP_WIN
|
||||||
content/browser/win6BrowserOverlay.xul (content/win6BrowserOverlay.xul)
|
content/browser/win6BrowserOverlay.xul (content/win6BrowserOverlay.xul)
|
||||||
#endif
|
#endif
|
||||||
content/browser/socialmarks.xml (content/socialmarks.xml)
|
|
||||||
content/browser/socialchat.xml (content/socialchat.xml)
|
content/browser/socialchat.xml (content/socialchat.xml)
|
||||||
# the following files are browser-specific overrides
|
# the following files are browser-specific overrides
|
||||||
* content/browser/license.html (/toolkit/content/license.html)
|
* content/browser/license.html (/toolkit/content/license.html)
|
||||||
|
|
|
@ -573,7 +573,7 @@ const CustomizableWidgets = [
|
||||||
node.setAttribute("label", CustomizableUI.getLocalizedProperty(this, "label"));
|
node.setAttribute("label", CustomizableUI.getLocalizedProperty(this, "label"));
|
||||||
node.setAttribute("tooltiptext", CustomizableUI.getLocalizedProperty(this, "tooltiptext"));
|
node.setAttribute("tooltiptext", CustomizableUI.getLocalizedProperty(this, "tooltiptext"));
|
||||||
node.setAttribute("removable", "true");
|
node.setAttribute("removable", "true");
|
||||||
node.setAttribute("observes", "Social:PageShareOrMark");
|
node.setAttribute("observes", "Social:PageShareable");
|
||||||
node.setAttribute("command", "Social:SharePage");
|
node.setAttribute("command", "Social:SharePage");
|
||||||
|
|
||||||
let listener = {
|
let listener = {
|
||||||
|
|
|
@ -4,8 +4,7 @@
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
this.EXPORTED_SYMBOLS = ["Social", "CreateSocialStatusWidget",
|
this.EXPORTED_SYMBOLS = ["Social", "OpenGraphBuilder",
|
||||||
"CreateSocialMarkWidget", "OpenGraphBuilder",
|
|
||||||
"DynamicResizeWatcher", "sizeSocialPanelToContent"];
|
"DynamicResizeWatcher", "sizeSocialPanelToContent"];
|
||||||
|
|
||||||
const Ci = Components.interfaces;
|
const Ci = Components.interfaces;
|
||||||
|
@ -32,46 +31,6 @@ XPCOMUtils.defineLazyModuleGetter(this, "Promise",
|
||||||
"resource://gre/modules/Promise.jsm");
|
"resource://gre/modules/Promise.jsm");
|
||||||
|
|
||||||
|
|
||||||
function promiseSetAnnotation(aURI, providerList) {
|
|
||||||
let deferred = Promise.defer();
|
|
||||||
|
|
||||||
// Delaying to catch issues with asynchronous behavior while waiting
|
|
||||||
// to implement asynchronous annotations in bug 699844.
|
|
||||||
Services.tm.mainThread.dispatch(function() {
|
|
||||||
try {
|
|
||||||
if (providerList && providerList.length > 0) {
|
|
||||||
PlacesUtils.annotations.setPageAnnotation(
|
|
||||||
aURI, "social/mark", JSON.stringify(providerList), 0,
|
|
||||||
PlacesUtils.annotations.EXPIRE_WITH_HISTORY);
|
|
||||||
} else {
|
|
||||||
PlacesUtils.annotations.removePageAnnotation(aURI, "social/mark");
|
|
||||||
}
|
|
||||||
} catch(e) {
|
|
||||||
Cu.reportError("SocialAnnotation failed: " + e);
|
|
||||||
}
|
|
||||||
deferred.resolve();
|
|
||||||
}, Ci.nsIThread.DISPATCH_NORMAL);
|
|
||||||
|
|
||||||
return deferred.promise;
|
|
||||||
}
|
|
||||||
|
|
||||||
function promiseGetAnnotation(aURI) {
|
|
||||||
let deferred = Promise.defer();
|
|
||||||
|
|
||||||
// Delaying to catch issues with asynchronous behavior while waiting
|
|
||||||
// to implement asynchronous annotations in bug 699844.
|
|
||||||
Services.tm.mainThread.dispatch(function() {
|
|
||||||
let val = null;
|
|
||||||
try {
|
|
||||||
val = PlacesUtils.annotations.getPageAnnotation(aURI, "social/mark");
|
|
||||||
} catch (ex) { }
|
|
||||||
|
|
||||||
deferred.resolve(val);
|
|
||||||
}, Ci.nsIThread.DISPATCH_NORMAL);
|
|
||||||
|
|
||||||
return deferred.promise;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.Social = {
|
this.Social = {
|
||||||
initialized: false,
|
initialized: false,
|
||||||
lastEventReceived: 0,
|
lastEventReceived: 0,
|
||||||
|
@ -180,65 +139,6 @@ this.Social = {
|
||||||
// It's OK if the provider has already been activated - we still get called
|
// It's OK if the provider has already been activated - we still get called
|
||||||
// back with it.
|
// back with it.
|
||||||
SocialService.enableProvider(origin, callback);
|
SocialService.enableProvider(origin, callback);
|
||||||
},
|
|
||||||
|
|
||||||
// Page Marking functionality
|
|
||||||
isURIMarked: function(origin, aURI, aCallback) {
|
|
||||||
promiseGetAnnotation(aURI).then(function(val) {
|
|
||||||
if (val) {
|
|
||||||
let providerList = JSON.parse(val);
|
|
||||||
val = providerList.indexOf(origin) >= 0;
|
|
||||||
}
|
|
||||||
aCallback(!!val);
|
|
||||||
}).then(null, Cu.reportError);
|
|
||||||
},
|
|
||||||
|
|
||||||
markURI: function(origin, aURI, aCallback) {
|
|
||||||
// update or set our annotation
|
|
||||||
promiseGetAnnotation(aURI).then(function(val) {
|
|
||||||
|
|
||||||
let providerList = val ? JSON.parse(val) : [];
|
|
||||||
let marked = providerList.indexOf(origin) >= 0;
|
|
||||||
if (marked)
|
|
||||||
return;
|
|
||||||
providerList.push(origin);
|
|
||||||
// we allow marking links in a page that may not have been visited yet.
|
|
||||||
// make sure there is a history entry for the uri, then annotate it.
|
|
||||||
let place = {
|
|
||||||
uri: aURI,
|
|
||||||
visits: [{
|
|
||||||
visitDate: Date.now() + 1000,
|
|
||||||
transitionType: Ci.nsINavHistoryService.TRANSITION_LINK
|
|
||||||
}]
|
|
||||||
};
|
|
||||||
PlacesUtils.asyncHistory.updatePlaces(place, {
|
|
||||||
handleError: () => Cu.reportError("couldn't update history for socialmark annotation"),
|
|
||||||
handleResult: function () {},
|
|
||||||
handleCompletion: function () {
|
|
||||||
promiseSetAnnotation(aURI, providerList).then(function() {
|
|
||||||
if (aCallback)
|
|
||||||
schedule(function() { aCallback(true); } );
|
|
||||||
}).then(null, Cu.reportError);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}).then(null, Cu.reportError);
|
|
||||||
},
|
|
||||||
|
|
||||||
unmarkURI: function(origin, aURI, aCallback) {
|
|
||||||
// this should not be called if this.provider or the port is null
|
|
||||||
// set our annotation
|
|
||||||
promiseGetAnnotation(aURI).then(function(val) {
|
|
||||||
let providerList = val ? JSON.parse(val) : [];
|
|
||||||
let marked = providerList.indexOf(origin) >= 0;
|
|
||||||
if (marked) {
|
|
||||||
// remove the annotation
|
|
||||||
providerList.splice(providerList.indexOf(origin), 1);
|
|
||||||
promiseSetAnnotation(aURI, providerList).then(function() {
|
|
||||||
if (aCallback)
|
|
||||||
schedule(function() { aCallback(false); } );
|
|
||||||
}).then(null, Cu.reportError);
|
|
||||||
}
|
|
||||||
}).then(null, Cu.reportError);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -246,73 +146,6 @@ function schedule(callback) {
|
||||||
Services.tm.mainThread.dispatch(callback, Ci.nsIThread.DISPATCH_NORMAL);
|
Services.tm.mainThread.dispatch(callback, Ci.nsIThread.DISPATCH_NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
function CreateSocialStatusWidget(aId, aProvider) {
|
|
||||||
if (!aProvider.statusURL)
|
|
||||||
return;
|
|
||||||
let widget = CustomizableUI.getWidget(aId);
|
|
||||||
// The widget is only null if we've created then destroyed the widget.
|
|
||||||
// Once we've actually called createWidget the provider will be set to
|
|
||||||
// PROVIDER_API.
|
|
||||||
if (widget && widget.provider == CustomizableUI.PROVIDER_API)
|
|
||||||
return;
|
|
||||||
|
|
||||||
CustomizableUI.createWidget({
|
|
||||||
id: aId,
|
|
||||||
type: "custom",
|
|
||||||
removable: true,
|
|
||||||
defaultArea: CustomizableUI.AREA_NAVBAR,
|
|
||||||
onBuild: function(aDocument) {
|
|
||||||
let node = aDocument.createElement("toolbarbutton");
|
|
||||||
node.id = this.id;
|
|
||||||
node.setAttribute("class", "toolbarbutton-1 chromeclass-toolbar-additional social-status-button badged-button");
|
|
||||||
node.style.listStyleImage = "url(" + (aProvider.icon32URL || aProvider.iconURL) + ")";
|
|
||||||
node.setAttribute("origin", aProvider.origin);
|
|
||||||
node.setAttribute("label", aProvider.name);
|
|
||||||
node.setAttribute("tooltiptext", aProvider.name);
|
|
||||||
node.setAttribute("oncommand", "SocialStatus.showPopup(this);");
|
|
||||||
node.setAttribute("constrain-size", "true");
|
|
||||||
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function CreateSocialMarkWidget(aId, aProvider) {
|
|
||||||
if (!aProvider.markURL)
|
|
||||||
return;
|
|
||||||
let widget = CustomizableUI.getWidget(aId);
|
|
||||||
// The widget is only null if we've created then destroyed the widget.
|
|
||||||
// Once we've actually called createWidget the provider will be set to
|
|
||||||
// PROVIDER_API.
|
|
||||||
if (widget && widget.provider == CustomizableUI.PROVIDER_API)
|
|
||||||
return;
|
|
||||||
|
|
||||||
CustomizableUI.createWidget({
|
|
||||||
id: aId,
|
|
||||||
type: "custom",
|
|
||||||
removable: true,
|
|
||||||
defaultArea: CustomizableUI.AREA_NAVBAR,
|
|
||||||
onBuild: function(aDocument) {
|
|
||||||
let node = aDocument.createElement("toolbarbutton");
|
|
||||||
node.id = this.id;
|
|
||||||
node.setAttribute("class", "toolbarbutton-1 chromeclass-toolbar-additional social-mark-button");
|
|
||||||
node.setAttribute("type", "socialmark");
|
|
||||||
node.setAttribute("constrain-size", "true");
|
|
||||||
node.style.listStyleImage = "url(" + (aProvider.unmarkedIcon || aProvider.icon32URL || aProvider.iconURL) + ")";
|
|
||||||
node.setAttribute("origin", aProvider.origin);
|
|
||||||
|
|
||||||
let window = aDocument.defaultView;
|
|
||||||
let menuLabel = window.gNavigatorBundle.getFormattedString("social.markpageMenu.label", [aProvider.name]);
|
|
||||||
node.setAttribute("label", menuLabel);
|
|
||||||
node.setAttribute("tooltiptext", menuLabel);
|
|
||||||
node.setAttribute("observes", "Social:PageShareOrMark");
|
|
||||||
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function sizeSocialPanelToContent(panel, iframe, requestedSize) {
|
function sizeSocialPanelToContent(panel, iframe, requestedSize) {
|
||||||
let doc = iframe.contentDocument;
|
let doc = iframe.contentDocument;
|
||||||
if (!doc || !doc.body) {
|
if (!doc || !doc.body) {
|
||||||
|
|
|
@ -503,7 +503,7 @@ this.SocialService = {
|
||||||
},
|
},
|
||||||
|
|
||||||
_manifestFromData: function(type, data, installOrigin) {
|
_manifestFromData: function(type, data, installOrigin) {
|
||||||
let featureURLs = ['sidebarURL', 'shareURL', 'statusURL', 'markURL'];
|
let featureURLs = ['sidebarURL', 'shareURL'];
|
||||||
let resolveURLs = featureURLs.concat(['postActivationURL']);
|
let resolveURLs = featureURLs.concat(['postActivationURL']);
|
||||||
|
|
||||||
if (type == 'directory' || type == 'internal') {
|
if (type == 'directory' || type == 'internal') {
|
||||||
|
@ -706,10 +706,6 @@ function SocialProvider(input) {
|
||||||
this.icon64URL = input.icon64URL;
|
this.icon64URL = input.icon64URL;
|
||||||
this.sidebarURL = input.sidebarURL;
|
this.sidebarURL = input.sidebarURL;
|
||||||
this.shareURL = input.shareURL;
|
this.shareURL = input.shareURL;
|
||||||
this.statusURL = input.statusURL;
|
|
||||||
this.markURL = input.markURL;
|
|
||||||
this.markedIcon = input.markedIcon;
|
|
||||||
this.unmarkedIcon = input.unmarkedIcon;
|
|
||||||
this.postActivationURL = input.postActivationURL;
|
this.postActivationURL = input.postActivationURL;
|
||||||
this.origin = input.origin;
|
this.origin = input.origin;
|
||||||
let originUri = Services.io.newURI(input.origin, null, null);
|
let originUri = Services.io.newURI(input.origin, null, null);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче