From f6ce087b3683283e3805a391a45f3a7a8871a937 Mon Sep 17 00:00:00 2001 From: Shane Caraveo Date: Tue, 13 May 2014 11:10:47 -0700 Subject: [PATCH] Bug 960991 support for standard share endpoints, r=markh --- browser/base/content/browser-social.js | 33 ++++++++++++++++++--- browser/base/content/browser.xul | 2 +- browser/base/content/socialmarks.xml | 15 +++++++--- browser/modules/Social.jsm | 20 +++++++++---- toolkit/components/social/SocialService.jsm | 7 +++++ 5 files changed, 62 insertions(+), 15 deletions(-) diff --git a/browser/base/content/browser-social.js b/browser/base/content/browser-social.js index 4d3a932a3803..47e4a4219d0f 100644 --- a/browser/base/content/browser-social.js +++ b/browser/base/content/browser-social.js @@ -615,7 +615,20 @@ SocialShare = { let shareEndpoint = OpenGraphBuilder.generateEndpointURL(provider.shareURL, pageData); - this._dynamicResizer = new DynamicResizeWatcher(); + let size = provider.getPageSize("share"); + if (size) { + if (this._dynamicResizer) { + this._dynamicResizer.stop(); + this._dynamicResizer = null; + } + let {width, height} = size; + width += this.panel.boxObject.width - iframe.boxObject.width; + height += this.panel.boxObject.height - iframe.boxObject.height; + this.panel.sizeTo(width, height); + } else { + this._dynamicResizer = new DynamicResizeWatcher(); + } + // if we've already loaded this provider/page share endpoint, we don't want // to add another load event listener. let reload = true; @@ -625,7 +638,8 @@ SocialShare = { reload = shareEndpoint != iframe.contentDocument.location.spec; } if (!reload) { - this._dynamicResizer.start(this.panel, iframe); + if (this._dynamicResizer) + this._dynamicResizer.start(this.panel, iframe); iframe.docShell.isActive = true; iframe.docShell.isAppTab = true; let evt = iframe.contentDocument.createEvent("CustomEvent"); @@ -637,6 +651,10 @@ SocialShare = { iframe.removeEventListener("load", panelBrowserOnload, true); iframe.docShell.isActive = true; iframe.docShell.isAppTab = true; + // to support standard share endpoints mimick window.open by setting + // window.opener, some share endpoints rely on w.opener to know they + // should close the window when done. + iframe.contentWindow.opener = iframe.contentWindow; setTimeout(function() { if (SocialShare._dynamicResizer) { // may go null if hidden quickly SocialShare._dynamicResizer.start(iframe.parentNode, iframe); @@ -1130,6 +1148,9 @@ SocialStatus = { } if (!frame) { + let size = provider.getPageSize("status"); + let {width, height} = size ? size : {width: PANEL_MIN_WIDTH, height: PANEL_MIN_HEIGHT}; + frame = SharedFrame.createFrame( notificationFrameId, /* frame name */ aParent, /* parent */ @@ -1144,7 +1165,8 @@ SocialStatus = { // work around bug 793057 - by making the panel roughly the final size // we are more likely to have the anchor in the correct position. - "style": "width: " + PANEL_MIN_WIDTH + "px;", + "style": "width: " + width + "px; height: " + height + "px;", + "dynamicresizer": !size, "origin": provider.origin, "src": provider.statusURL @@ -1246,7 +1268,10 @@ SocialStatus = { } // we only use a dynamic resizer when we're located the toolbar. - let dynamicResizer = inMenuPanel ? null : this._dynamicResizer; + let dynamicResizer; + if (!inMenuPanel && notificationFrame.getAttribute("dynamicresizer") == "true") { + dynamicResizer = this._dynamicResizer; + } panel.addEventListener(hidingEvent, function onpopuphiding() { panel.removeEventListener(hidingEvent, onpopuphiding); aToolbarButton.removeAttribute("open"); diff --git a/browser/base/content/browser.xul b/browser/base/content/browser.xul index f18b5465172a..a9ac674ec281 100644 --- a/browser/base/content/browser.xul +++ b/browser/base/content/browser.xul @@ -244,7 +244,7 @@ onpopuphidden="SocialShare.onHidden()" hidden="true"> - + diff --git a/browser/base/content/socialmarks.xml b/browser/base/content/socialmarks.xml index 5ca27a42f159..dddf6e86a526 100644 --- a/browser/base/content/socialmarks.xml +++ b/browser/base/content/socialmarks.xml @@ -17,6 +17,7 @@ xbl:inherits="xbl:text=label,accesskey,wrap"/> + false false @@ -37,6 +38,11 @@ if (this._frame) return this._frame; let notificationFrameId = "social-mark-frame-" + this.getAttribute("origin"); + let provider = Social._getProviderFromOrigin(this.getAttribute("origin")); + let size = provider.getPageSize("marks"); + let {width, height} = size ? size : {width: 330, height: 100}; + this._useDynamicResizer = !size; + this._frame = SharedFrame.createFrame( notificationFrameId, /* frame name */ this.panel, /* parent */ @@ -49,7 +55,8 @@ "flex": "1", "context": "contentAreaContextMenu", "origin": this.getAttribute("origin"), - "src": "about:blank" + "src": "about:blank", + "style": "width: " + width + "px; height: " + height + "px;", } ); this._frame.addEventListener("DOMLinkAdded", this); @@ -150,7 +157,7 @@ this._loading = false; this.content.removeEventListener("DOMContentLoaded", DOMContentLoaded, true); // add our resizer after the dom is ready - if (!this.inMenuPanel) { + if (!this.inMenuPanel && this._useDynamicResizer) { let DynamicResizeWatcher = Cu.import("resource:///modules/Social.jsm", {}).DynamicResizeWatcher; this._dynamicResizer = new DynamicResizeWatcher(); this._dynamicResizer.start(this.panel, this.content); @@ -280,13 +287,13 @@ if (!this._loading && this.contentDocument && this.contentDocument.readyState == "complete") { this.dispatchPanelEvent("socialFrameShow"); - if (!this.inMenuPanel) + if (!this.inMenuPanel && this._useDynamicResizer) sizeSocialPanelToContent(this.panel, this.content); } else { let panelBrowserOnload = (e) => { this.content.removeEventListener("load", panelBrowserOnload, true); this.dispatchPanelEvent("socialFrameShow"); - if (!this.inMenuPanel) + if (!this.inMenuPanel && this._useDynamicResizer) sizeSocialPanelToContent(this.panel, this.content); }; this.content.addEventListener("load", panelBrowserOnload, true); diff --git a/browser/modules/Social.jsm b/browser/modules/Social.jsm index 1e8e7759b28d..fed90c10be87 100644 --- a/browser/modules/Social.jsm +++ b/browser/modules/Social.jsm @@ -413,11 +413,16 @@ function sizeSocialPanelToContent(panel, iframe) { let computedWidth = parseInt(cs.marginLeft) + body.offsetWidth + parseInt(cs.marginRight); width = Math.max(computedWidth, width); } - iframe.style.width = width + "px"; - iframe.style.height = height + "px"; - // since we do not use panel.sizeTo, we need to adjust the arrow ourselves - if (panel.state == "open") - panel.adjustArrowPosition(); + // add extra space the panel needs if any + width += panel.boxObject.width - iframe.boxObject.width; + height += panel.boxObject.height - iframe.boxObject.height; + + // when size is computed, we want to be sure changes are "significant" since + // some sites will resize when the iframe is resized by a small amount, making + // the panel slowely shrink to some minimum. + if (Math.abs(panel.boxObject.width - width) > 2 || Math.abs(panel.boxObject.height - height) > 2) { + panel.sizeTo(width, height); + } } function DynamicResizeWatcher() { @@ -468,7 +473,10 @@ this.OpenGraphBuilder = { // preserve non-template query vars query[name] = value; } else if (pageData[p[1]]) { - query[name] = 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 = ""; diff --git a/toolkit/components/social/SocialService.jsm b/toolkit/components/social/SocialService.jsm index 996f7cac961c..2dd63794e99f 100644 --- a/toolkit/components/social/SocialService.jsm +++ b/toolkit/components/social/SocialService.jsm @@ -792,6 +792,13 @@ SocialProvider.prototype = { return SocialService.getManifestByOrigin(this.origin); }, + getPageSize: function(name) { + let manifest = this.manifest; + if (manifest && manifest.pageSize) + return manifest.pageSize[name]; + return undefined; + }, + // Reference to a workerAPI object for this provider. Null if the provider has // no FrameWorker, or is disabled. workerAPI: null,