зеркало из https://github.com/mozilla/gecko-dev.git
Bug 797716 - improvements to the auto-resize code for social panels. r=felipe
This commit is contained in:
Родитель
6257438cdb
Коммит
21cdb29a01
|
@ -2,6 +2,10 @@
|
|||
// 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/.
|
||||
|
||||
// The minimum sizes for the auto-resize panel code.
|
||||
const PANEL_MIN_HEIGHT = 300;
|
||||
const PANEL_MIN_WIDTH = 330;
|
||||
|
||||
let SocialUI = {
|
||||
// Called on delayed startup to initialize UI
|
||||
init: function SocialUI_init() {
|
||||
|
@ -199,42 +203,49 @@ let SocialChatBar = {
|
|||
function sizeSocialPanelToContent(iframe) {
|
||||
// FIXME: bug 764787: Maybe we can use nsIDOMWindowUtils.getRootBounds() here?
|
||||
let doc = iframe.contentDocument;
|
||||
if (!doc) {
|
||||
if (!doc || !doc.body) {
|
||||
return;
|
||||
}
|
||||
// "notif" is an implementation detail that we should get rid of
|
||||
// eventually
|
||||
let body = doc.getElementById("notif") || doc.body;
|
||||
if (!body) {
|
||||
return;
|
||||
}
|
||||
// XXX - do we want a max for width and height here?
|
||||
// The 300 and 330 defaults also seem arbitrary, so should be revisited.
|
||||
// BUT - for at least one provider, the scrollWidth/offsetWidth/css width
|
||||
// isn't set appropriately, so the 330 is "fixed" for now...
|
||||
iframe.style.width = "330px";
|
||||
// offsetHeight doesn't include margins, so account for that.
|
||||
let body = doc.body;
|
||||
// offsetHeight/Width don't include margins, so account for that.
|
||||
let cs = doc.defaultView.getComputedStyle(body);
|
||||
let computedHeight = parseInt(cs.marginTop) + body.offsetHeight + parseInt(cs.marginBottom);
|
||||
let height = computedHeight || 300;
|
||||
let height = Math.max(computedHeight, PANEL_MIN_HEIGHT);
|
||||
iframe.style.height = height + "px";
|
||||
let computedWidth = parseInt(cs.marginLeft) + body.offsetWidth + parseInt(cs.marginRight);
|
||||
let width = Math.max(computedWidth, PANEL_MIN_WIDTH);
|
||||
iframe.style.width = width + "px";
|
||||
}
|
||||
|
||||
function setupDynamicPanelResizer(iframe) {
|
||||
let doc = iframe.contentDocument;
|
||||
let mo = new iframe.contentWindow.MutationObserver(function(mutations) {
|
||||
function DynamicResizeWatcher() {
|
||||
this._mutationObserver = null;
|
||||
}
|
||||
|
||||
DynamicResizeWatcher.prototype = {
|
||||
start: function DynamicResizeWatcher_start(iframe) {
|
||||
this.stop(); // just in case...
|
||||
let doc = iframe.contentDocument;
|
||||
this._mutationObserver = new iframe.contentWindow.MutationObserver(function(mutations) {
|
||||
sizeSocialPanelToContent(iframe);
|
||||
});
|
||||
// Observe anything that causes the size to change.
|
||||
let config = {attributes: true, characterData: true, childList: true, subtree: true};
|
||||
this._mutationObserver.observe(doc, config);
|
||||
// and since this may be setup after the load event has fired we do an
|
||||
// initial resize now.
|
||||
sizeSocialPanelToContent(iframe);
|
||||
});
|
||||
// Observe anything that causes the size to change.
|
||||
let config = {attributes: true, characterData: true, childList: true, subtree: true};
|
||||
mo.observe(doc, config);
|
||||
doc.addEventListener("unload", function() {
|
||||
if (mo) {
|
||||
mo.disconnect();
|
||||
mo = null;
|
||||
},
|
||||
stop: function DynamicResizeWatcher_stop() {
|
||||
if (this._mutationObserver) {
|
||||
try {
|
||||
this._mutationObserver.disconnect();
|
||||
} catch (ex) {
|
||||
// may get "TypeError: can't access dead object" which seems strange,
|
||||
// but doesn't seem to indicate a real problem, so ignore it...
|
||||
}
|
||||
this._mutationObserver = null;
|
||||
}
|
||||
}, false);
|
||||
sizeSocialPanelToContent(iframe);
|
||||
}
|
||||
}
|
||||
|
||||
let SocialFlyout = {
|
||||
|
@ -272,15 +283,18 @@ let SocialFlyout = {
|
|||
|
||||
onShown: function(aEvent) {
|
||||
let iframe = this.panel.firstChild;
|
||||
this._dynamicResizer = new DynamicResizeWatcher();
|
||||
iframe.docShell.isActive = true;
|
||||
iframe.docShell.isAppTab = true;
|
||||
if (iframe.contentDocument.readyState == "complete") {
|
||||
this._dynamicResizer.start(iframe);
|
||||
this.dispatchPanelEvent("socialFrameShow");
|
||||
} else {
|
||||
// first time load, wait for load and dispatch after load
|
||||
iframe.addEventListener("load", function panelBrowserOnload(e) {
|
||||
iframe.removeEventListener("load", panelBrowserOnload, true);
|
||||
setTimeout(function() {
|
||||
SocialFlyout._dynamicResizer.start(iframe);
|
||||
SocialFlyout.dispatchPanelEvent("socialFrameShow");
|
||||
}, 0);
|
||||
}, true);
|
||||
|
@ -288,6 +302,8 @@ let SocialFlyout = {
|
|||
},
|
||||
|
||||
onHidden: function(aEvent) {
|
||||
this._dynamicResizer.stop();
|
||||
this._dynamicResizer = null;
|
||||
this.panel.firstChild.docShell.isActive = false;
|
||||
this.dispatchPanelEvent("socialFrameHide");
|
||||
},
|
||||
|
@ -305,7 +321,6 @@ let SocialFlyout = {
|
|||
if (src != aURL) {
|
||||
iframe.addEventListener("load", function documentLoaded() {
|
||||
iframe.removeEventListener("load", documentLoaded, true);
|
||||
setupDynamicPanelResizer(iframe);
|
||||
if (aCallback) {
|
||||
try {
|
||||
aCallback(iframe.contentWindow);
|
||||
|
@ -538,6 +553,7 @@ var SocialToolbar = {
|
|||
this.button.setAttribute("image", Social.provider.iconURL);
|
||||
this.updateButton();
|
||||
this.updateProfile();
|
||||
this._dynamicResizer = new DynamicResizeWatcher();
|
||||
},
|
||||
|
||||
get button() {
|
||||
|
@ -678,9 +694,11 @@ var SocialToolbar = {
|
|||
notificationFrame.contentDocument.documentElement.dispatchEvent(evt);
|
||||
}
|
||||
|
||||
let dynamicResizer = this._dynamicResizer;
|
||||
panel.addEventListener("popuphidden", function onpopuphiding() {
|
||||
panel.removeEventListener("popuphidden", onpopuphiding);
|
||||
aToolbarButtonBox.removeAttribute("open");
|
||||
dynamicResizer.stop();
|
||||
notificationFrame.docShell.isActive = false;
|
||||
dispatchPanelEvent("socialFrameHide");
|
||||
});
|
||||
|
@ -691,13 +709,13 @@ var SocialToolbar = {
|
|||
notificationFrame.docShell.isActive = true;
|
||||
notificationFrame.docShell.isAppTab = true;
|
||||
if (notificationFrame.contentDocument.readyState == "complete") {
|
||||
setupDynamicPanelResizer(notificationFrame);
|
||||
dynamicResizer.start(notificationFrame);
|
||||
dispatchPanelEvent("socialFrameShow");
|
||||
} else {
|
||||
// first time load, wait for load and dispatch after load
|
||||
notificationFrame.addEventListener("load", function panelBrowserOnload(e) {
|
||||
notificationFrame.removeEventListener("load", panelBrowserOnload, true);
|
||||
setupDynamicPanelResizer(notificationFrame);
|
||||
dynamicResizer.start(notificationFrame);
|
||||
setTimeout(function() {
|
||||
dispatchPanelEvent("socialFrameShow");
|
||||
}, 0);
|
||||
|
|
Загрузка…
Ссылка в новой задаче