Tuesday, April 10, 2012

Don't kill setAutoResize, it works...

Image courtesy Softicons

In fact it does not work :(
If you have ever developed an iframe based canvas app for Facebook, you know this.
You may say,
"Well .... it works but not as the name suggests. It just grows the iframe height but never shrinks. That is why Facebook has decided to change its name to setAutoGrow :)"
However, there is a way to make setAutoResize work as the name suggests. [How can I tell this to Facebook developers?]

Read on if you are interested in full story.

The Problem:
When you create a web application that runs in an iframe on the web property of someone else, you are limited by the space provider for the layout, placement and sizing.
Facebook is one such space provider. It provides the space in form of iframe so that the apps can embed functionality within Facebook.

When the content in the iframe grows, ugly scrollbars show up.
For the new design of Shopping Community feature of ShopSocially, there was a need to resize the frame.

The Struggle:
Solution is to monitor the height of the content inside the iframe and communicate it to the parent window. The script in the parent window listens to the message and sets the height of the iframe.

I started with communicating $(document).height() [yes I had the luxury of using jquery here] but some browsers [you know who .... :)] were still showing scrollbar. So I thought of adding 30 extra pixels to the height.
Now, every time $(document).height() returns those 30 px added and I was adding 30 more :(. This was a real auto-grow.

Using $('body').height() solved the issue of auto grow but it stopped growing even when there was an absolutely positioned light-box popup :(.

The Hope:
Facebook has provided a method [FB.canvas.setAutoResize()] to the applications for starting a timer that monitors the size of the content in the iframe and communicate it to the parent window. Facebook script in the parent window listens to the message and sets the size of iframe.

However, the FB.canvas.setAutoResize() method works in a way that the height of iframe only grows and never shrinks. So rather than fixing the issue, Facebook has renamed the method to FB.canvas.setAutoGrow() that better describes the behavior :(.

The discovery:
Anyways, I thought of looking at the implementation done by Facebook guys. The code in _computeContentSize function looks somewhat complicated but works same as the jquery code I was using. Even the comment by the developer of that code says the same.

However, I observed that right edge of every element was being determined and max of it is being communicated as width. Ohh .... so this was the source of my Dancing UI problem. I don't know why but same was not happening for height.

The Solution:
I decided to give it a try. For my code I determined the max of bottom of the popup element and the page and used that as height.

Bingo!! That actually worked for me. Size of the iframe grows as content adds to it. If you go to the bottom and view all comments of a product, you will see a popup and the iframe grows to make the complete popup visible. The beauty starts when you close the popup, the iframe shrinks back to fit in the content size.

If it works for me, it will work for Facebook too and app developer's will smile :)