Simpiflied iframe sizing in preview_iframe.tpl

Skinning and designing Serendipity (CSS, HTML, Smarty)
Post Reply
yellowled
Regular
Posts: 7111
Joined: Fri Jan 13, 2006 11:46 am
Location: Eutin, Germany
Contact:

Simpiflied iframe sizing in preview_iframe.tpl

Post by yellowled »

I came up with this yesterday while debugging a miscalculated height in Next's preview_iframe.tpl. I think it greatly simplifies the iframe height calculation, and I'm almost sure it does not have any side effects. I would not backport this to older themes, but use it in new ones. Still interested in thoughts and inputs, though.

So here's how we usually calculate the height for the iframe which displays the backend preview in inline JS:

Code: Select all

parent.document.getElementById('serendipity_iframe').style.height = document.getElementById('main').offsetHeight
+ parseInt(document.getElementById('main').style.marginTop)
+ parseInt(document.getElementById('main').style.marginBottom)
+ 'px';
which translates to “get the height of the element with the id main including vertical padding + its top margin + its bottom margin + in pixels”. A lot of themes use markup similar to this in the body to make this more or less easy to calculate:

Code: Select all

<body style="padding: 0; margin: 0;">
    <div id="main" style="padding: 0; margin: 5px auto; width: 98%;">
    […]
    </div>
<body>
which of course is kind of nuts because it may completely distort the way that #main is supposed to be displayed, just in order to get the preview right.

So here's the easier JS for that:

Code: Select all

parent.document.getElementById('serendipity_iframe').style.height = document.getElementById('preview_iframe').offsetHeight + 'px';
which requires us to – only in the preview_iframe.tpl! – use this

Code: Select all

<html id="preview" lang="{$lang}">
That way, our piece of JS will only have to calculate the height of the <html> element (yes, it is valid to assign an id to that element; no, it is not “dirty”). <html> usually does not have any margins, in many cases it won't have padding either. And here's the great thing (for those of use who hate inline styles with a passion):

Code: Select all

<body>
    <div id="main">
    […]
    </div>
<body>
That is basically what Next uses now, and it works like a charm with a lot less code and a lot less to think about. The only potential issue I see is if a theme's <html> already has an id for whatever reason, and that just means we'd have to use that id in the calculation JS.

Does anyone see any possible side effects? Because I don't.

YL
onli
Regular
Posts: 2822
Joined: Tue Sep 09, 2008 10:04 pm
Contact:

Re: Simpiflied iframe sizing in preview_iframe.tpl

Post by onli »

Couldn't you just select the html element in in the iframe, without using any id?

Otherwise that seems like a good idea, resulting in less needed boilerplate and less possible errors.
yellowled wrote:Does anyone see any possible side effects? Because I don't.
For feedtragón, I was using some js to determine which element is visible inside the viewport. For that code I used different approaches to get the height of element, because – as far as I remember – offsetHeight was not reliable. Won't matter here much, as the current code already uses offsetHeight and the change is unlikely to trigger anything. Just let's have that in mind.
yellowled
Regular
Posts: 7111
Joined: Fri Jan 13, 2006 11:46 am
Location: Eutin, Germany
Contact:

Re: Simpiflied iframe sizing in preview_iframe.tpl

Post by yellowled »

onli wrote:Couldn't you just select the html element in in the iframe, without using any id?
There is document.querySelector which can get elements as well. It's not supported in old browsers like IE8, though.

IMO, document.querySelector('html') is not that big of a gain over document.getElementById('preview_iframe'), even considering the saved id on the <html> element.

YL
onli
Regular
Posts: 2822
Joined: Tue Sep 09, 2008 10:04 pm
Contact:

Re: Simpiflied iframe sizing in preview_iframe.tpl

Post by onli »

http://caniuse.com/#search=querySelector looks pretty good, and IE8 can use it partly, for 'html' it should be good enough. See https://msdn.microsoft.com/en-us/librar ... s.85).aspx.

We could also use iframe.contentDocument instead. Or just getElementsByTagName, that is supported everywhere since forever.

It is not too important, but if we already simplify it it would be nice to make it just a bit more easy.

Anyway, I even think we should add this simplification to at least the recommended themes as well, so it is there as an example on how to do it for new themes.
yellowled
Regular
Posts: 7111
Joined: Fri Jan 13, 2006 11:46 am
Location: Eutin, Germany
Contact:

Re: Simpiflied iframe sizing in preview_iframe.tpl

Post by yellowled »

onli wrote:Anyway, I even think we should add this simplification to at least the recommended themes as well, so it is there as an example on how to do it for new themes.
Makes sense, I'll get right to it.

YL
garvinhicking
Core Developer
Posts: 30022
Joined: Tue Sep 16, 2003 9:45 pm
Location: Cologne, Germany
Contact:

Re: Simpiflied iframe sizing in preview_iframe.tpl

Post by garvinhicking »

Good work on that, that sounds like a great simplification. Thanks! :)
# Garvin Hicking (s9y Developer)
# Did I help you? Consider making me happy: http://wishes.garv.in/
# or use my PayPal account "paypal {at} supergarv (dot) de"
# My "other" hobby: http://flickr.garv.in/
yellowled
Regular
Posts: 7111
Joined: Fri Jan 13, 2006 11:46 am
Location: Eutin, Germany
Contact:

Re: Simpiflied iframe sizing in preview_iframe.tpl

Post by yellowled »

garvinhicking wrote:Good work on that, that sounds like a great simplification. Thanks! :)
“Just trying to help out Garvin” as a wise man used to have in his forum signature.

For those interested, here's how we use it now. JS (vanilla) code required in preview_iframe.tpl:

Code: Select all

<script type="text/javascript">
window.onload = function() {ldelim}
    parent.document.getElementById('serendipity_iframe').style.height = document.querySelector('html').offsetHeight + 'px';
    parent.document.getElementById('serendipity_iframe').scrolling    = 'no';
    parent.document.getElementById('serendipity_iframe').style.border = 0;
{rdelim}
</script>
With that, no element in the preview's body needs inline styles, the height will be calculated based solely on the html element (which is unique, so it does not need an id). Very excited to see if this really works for all future themes. (Again, I would not backport it to the old stuff, that's just not worth the effort and a good reason to switch to a new theme.)

YL
Post Reply