Custom Controls using Screen Overlays or IFRAME shims

1,273 views
Skip to first unread message

dorjee

unread,
Dec 8, 2009, 2:05:10 AM12/8/09
to KML Developer Support - Google Earth Plug-in
Hi,

I had a sight on the "Custom Controls using Screen Overlays or IFRAME
shims" demo (http://earth-api-samples.googlecode.com/svn/trunk/demos/
customcontrols/index.html) and I tried to understand the functionning.
But I am not a specialist in JS and I changed the code as I can, but
the result is not very satisfying.

Is it possible that some specialist in programmation proposes here a
short and very simple commented example of code? I precise:

- In Google Earth API (plugin)
- A button displayed on Earth screen
- A button displayed as an image (online path)
- A button with dimensions (width/height)
- A button with positions (top/left)
- A button with mouse link cursor on mouse over
- A button with a small visual effect on mouse over (like clearing)
- A button with an onclick function to download a kml file

Thanks in advance for an answer which could be integrated into the
demo gallery as a "Button basic demo".

dorjee

unread,
Dec 10, 2009, 1:37:21 PM12/10/09
to KML Developer Support - Google Earth Plug-in
Any body to help? Pleaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaase!

Nymor

unread,
Dec 10, 2009, 7:02:41 PM12/10/09
to KML Developer Support - Google Earth Plug-in
I'm with you on this dorjee - so am adding my support to your plea :)

I think I'm relatively proficient with the Plugin and have bashed
through the javascript needed but I too am a little bit confused with
the examples of the shim.

I have a couple of sites which could benefit from the technique - even
if only to allow qTips to appear above the GE pane - as opposed to
having GE go full screen with dialogs above it etc.

A 101 in the form of a narrative ... create div ... put GE in div ...
do ? with iframe ... would be very useful.

(To show willing ... once sussed I'd me more than happy to put
together and host a tutorial page with the various stages building up
to working example)

Nymor

Markw65

unread,
Dec 10, 2009, 7:31:09 PM12/10/09
to KML Developer Support - Google Earth Plug-in


On Dec 10, 4:02 pm, Nymor wrote:
>
> A 101 in the form of a narrative ... create div ... put GE in div ...
> do ? with iframe ... would be very useful.
>
i) Create a div
ii) Create an iframe, set its style to "position:absolute;height:
100%;width:100%;z-index:-1", its src to "about:blank", and insert it
as the first child of the div.
iii) Put whatever other content you want in the div.

Note that in step ii) the z-index will probably not be needed, since
the iframe is the first element in the div (or, if you have other
things in the div with -ve z-index, you may need to use a more
negative value).

Also, if you cant put the iframe inside the div (and I cant really
think of a good reason, unless you have no control over the contents
of the div), you can instead give it the same z-index as the div,
insert it in the dom just before the div, and position and size it
absolutely so that its right behind the div. The downside of that is
that every time you move or resize the div, you have to move and
resize the iframe (whereas in the above, it happens automatically).

Finally, in FF, you have to make sure the iframe is created /after/
you first show the earth instance - or at least that its inserted into
the dom after you first show the earth instance. Note that its ok to
simply remove/re-insert the iframe each time you show the earth
instance, just to be safe.

Mark

dorjee

unread,
Dec 11, 2009, 2:06:26 AM12/11/09
to KML Developer Support - Google Earth Plug-in
Thank you Markw65 to describe a good method, but being not a
specialist, an example code should be welcome...
Here is one I made after long explorations, based on the overlay
method. This is a HTML file displaying a GE plugin map.

<html><head><title>Title of your HTML page</title>
<script src="http://www.google.com/jsapi?key= put your Google Key
here "></script>
<script type="text/javascript">
var ge;
google.load("earth", "1");

function init() {google.earth.createInstance('map3d', initCallback,
failureCallback);}

function initCallback(pluginInstance) {
ge = pluginInstance;
ge.getWindow().setVisibility(true);

// etc. put here all necessary code to display
// your map, placemark, etc.

//define here the position top and left
//and the dimension width and height
//of your button
createScreenOverlayButton(10, 10, 24, 24);}

function failureCallback(errorCode) {}

//from here all the necessary code
//to display and manage the button
function addDomListener(element, eventName, listener) {
if (element.addEventListener)
element.addEventListener(eventName, listener, false);
else if (element.attachEvent)
element.attachEvent('on' + eventName, listener);}
function getElementRect(element) {
var left = element.offsetLeft;
var top = element.offsetTop;
var p = element.offsetParent;
while (p && p != document.body.parentNode) {
if (isFinite(p.offsetLeft) && isFinite(p.offsetTop)) {
left += p.offsetLeft;
top += p.offsetTop;}
p = p.offsetParent;}
return {left: left, top: top, width: element.offsetWidth, height:
element.offsetHeight};}
function createScreenOverlayButton(x, y, width, height) {
var _addOverlayForState = function(suffix, drawOrder, visible) {
var icon = ge.createIcon('');

//here, very important, enter the web
//path and prefix of your button images
//I explain: make three versions of your
//image button that you name:
// (1): MyButton.png
// (2): MyButton_hover.png
// (3): MyButton_down.png
//say one version is blue, the other grey,
//and the third version green
//this will make a color effect when mouse
//cursor fly over the button (_hover) and
//when you click the button (_down)
//note extension is PNG, change it as you need
icon.setHref('http://www.mywebsite.com/images/kml-button' + suffix +
'.png');

//code continuing ...
var overlay = ge.createScreenOverlay('');
overlay.setDrawOrder(drawOrder || 0);
overlay.setVisibility(visible || false);
overlay.setIcon(icon);
overlay.getOverlayXY().set(x, ge.UNITS_PIXELS, y,
ge.UNITS_INSET_PIXELS);
overlay.getScreenXY().set(0, ge.UNITS_FRACTION, 1, ge.UNITS_FRACTION);
overlay.getSize().set(width, ge.UNITS_PIXELS, height,
ge.UNITS_PIXELS);
ge.getFeatures().appendChild(overlay);
return overlay;};
var overlayReg = _addOverlayForState('', 1, true);
var overlayHover = _addOverlayForState('_hover', 2, false);
var overlayDown = _addOverlayForState('_down', 3, false);
var _setState = function(state) {
overlayHover.setVisibility(state == 'hover');
overlayDown.setVisibility(state == 'down');};
var _isMouseOnButton = function(mx, my) {
return x <= mx && mx <= x + width && y <= my && my <= y + height;};
var buttonDown = false;
google.earth.addEventListener(ge.getWindow(), 'mousedown', function
(evt) {
if (evt.getButton() != 0)
return;
if (_isMouseOnButton(evt.getClientX(), evt.getClientY())) {
buttonDown = true;
_setState('down');
event.preventDefault();
return false;}});
google.earth.addEventListener(ge.getWindow(), 'mousemove', function
(evt) {
if (_isMouseOnButton(evt.getClientX(), evt.getClientY())) {
_setState(buttonDown ? 'down' : 'hover');} else {_setState
(buttonDown ? 'hover' : '');}
if (buttonDown) {event.preventDefault();
return false;}});
google.earth.addEventListener(ge.getWindow(), 'mouseup', function(evt)
{
if (buttonDown) {
buttonDown = false;
_setState(_isMouseOnButton(evt.getClientX(), evt.getClientY()) ?
'hover' : '');
event.preventDefault();
return false;}});
google.earth.addEventListener(ge.getWindow(), 'click', function(evt) {
if (evt.getButton() === 0 && _isMouseOnButton(evt.getClientX(),
evt.getClientY())) {

//important here too: enter the link of a file (say a KML file)
//that you want the user download when button is clicked
document.location='http://www.mywebsite.com/kml/myKMLfile.kml';

/code is continuing ...
buttonDown = false;}});}
</script></head>
<body onload="init()">
<div id="map3d" style="width: 500px; height: 500px;"></div>
</body></html>

Now I intend to make another post because I would like the cursor is
changing over the button and a tooltip is displayed ...

Nymor

unread,
Dec 21, 2009, 1:23:26 PM12/21/09
to KML Developer Support - Google Earth Plug-in
A much belated thanks Mark for your tips.

I think I've got it now - the penny finally dropped when I realised
that the iframe is just a completely blank element. The demo page you
have in the examples also confused me slightly as I originally thought
the pop-up windows you have in that were done with iframe shims - but
once I realised it's just the + symbols around the edge that are shims
it became a bit clearer.

I also found this quote on a site that made me go ... ahhh that's what
it's about.

"The IFRAME control has a unique nature. It can exist in both the
zIndex of
windowed controls and the zIndex of regular HTML elements."


Couple more quick questions if I may though....

1. I've read the previous posts from a while ago that reference the
issue of allowTransparency not working and wondered if anyone had
managed to find a work-around for this or whether it's still the same.
(In my case I want to put rounded corners on my shims but this needs
GE to show through via transparency).

2. Is there a technical reason (Mark) that you use Prototype Windows
for your pop-ups and didn't do them as shimmed html - or was it just
because that's how you did it at the time. I only ask as I'm going
down the route of shimmed html but if you know of issues with that
then I'll reconsider. (If I do have to go down that route does anyone
know an equivalent Window control for jQuery - couldn't find one?)


Thanks again Mark for your pointers - very helpful.

Kindest regards
Nymor

Markw65

unread,
Dec 21, 2009, 2:55:01 PM12/21/09
to KML Developer Support - Google Earth Plug-in


On Dec 21, 10:23 am, Nymor wrote:
> A much belated thanks Mark for your tips.
>
> I think I've got it now - the penny finally dropped when I realised
> that the iframe is just a completely blank element. The demo page you
> have in the examples also confused me slightly as I originally thought
> the pop-up windows you have in that were done with iframe shims - but
> once I realised it's just the + symbols around the edge that are shims
> it became a bit clearer.

Sorry to muddy the waters then, but the popups /are/ done using iframe
shims. How else?

The only difference is that they do it the "hard" way, using absolute
positioning to put the shim behind the window (and updating the shim
every time the window is moved/resized), rather than the much easier
solution of putting the shim inside the window and having it resize
automatically with the window.

This is just because the "Prototype window class" already had code for
doing this. It was badly broken, unfortunately, and by the time I was
done Id rewritten most of it...

Note that the "+" symbols, on the other hand, are done using a
combination of screenOverlay, and iframe shims. The screenOverlay to
allow for transparency/rounded corners around the edges, and the
iframe shim to allow for arbitrary content, and control over the
cursor (neither of these is exploited much, but it was just supposed
to be a proof of concept). Also, using the shims allows me to use the
same controls when the map is switched to 2D mode.

> Couple more quick questions if I may though....
>
> 1. I've read the previous posts from a while ago that reference the
> issue of allowTransparency not working and wondered if anyone had
> managed to find a work-around for this or whether it's still the same.
> (In my case I want to put rounded corners on my shims but this needs
> GE to show through via transparency).

Not as far as I know. But my demo does include a function to create a
"rounded corner" shim (and you can see the effect on the popup
windows). Basically, it creates a set of nested iframes, which overlap
in just the right way to create the rounded corners. It works
surprisingly well.

>
> 2. Is there a technical reason (Mark) that you use Prototype Windows
> for your pop-ups and didn't do them as shimmed html - or was it just
> because that's how you did it at the time. I only ask as I'm going
> down the route of shimmed html but if you know of issues with that
> then I'll reconsider. (If I do have to go down that route does anyone
> know an equivalent Window control for jQuery - couldn't find one?)

I used prototype windows because it already had some of the support I
wanted (although, as I said above, it turned out to be so buggy that I
ended up re-implementing most of the support myself). I've since
switched to jQuery for all my new work (but havent had time to update
all my old code).

And I have a nice jquery plugin which handles everything. Its
basically bgiFrame, modified to work with all browsers (rather than
just ie6). I'm afraid its somewhat mixed up with the rest of my code -
I'll try to separate it out, and put up a demo. But the quickly
extracted (and untested) code looks like this:

function prop(n,d){return !n||n=='auto'?
d:n&&n.constructor==Number?n+'px':n;}
function createMask(s,cn) {
var shim = document.createElement('div');
shim.className = cn+"-mask";
shim.style.border = "0px";
shim.style.position = "absolute";
shim.style.zIndex = -1;
shim.style.height = prop(s.height,"100%");
shim.style.width = prop(s.width,"100%");
shim.style.left = prop(s.left,"0");
shim.style.top = prop(s.top,"0");
if (s.mask_color)
shim.style.backgroundColor = s.mask_color;
$(shim).css({opacity:s.opacity||0.001});
return shim;
}
$.fn.bgIframe = $.fn.bgiframe = $.bgiframe = function(s) {
if (typeof s == "string") {
var items = this;
if (this === $) {
items = $('.bgiframe');
}
if (s == "fix") {
// In FF, if an iframe is created before the
object its
// trying to shim, it doesnt work. We have to
remove, and
// re-insert it
items.each(function() {
var s = this.nextSibling;
var p = this.parentNode;
p.removeChild(this);
p.insertBefore(this,s);
});
} else if (s == "remove") {
items.parent().find(".bgiframe-mask").remove();
items.remove();
} else {
throw "unknown bgiframe method: "+s;
}
} else if (this.length) {
s = $.extend({
top : 'auto', // auto
== .currentStyle.borderTopWidth
left : 'auto', // auto
== .currentStyle.borderLeftWidth
width : 'auto', // auto == offsetWidth
height : 'auto', // auto == offsetHeight
src : 'about:blank',
zIndex : -1,
mask_color : "white"
}, s || {});
var cn = s.eclass ? s.eclass + " " : "";
cn += "bgiframe";
function createShim() {
var shim = document.createElement('iframe');
shim.frameBorder = 0;
shim.scrolling = "no";
shim.src = s.src;
shim.className = cn;
shim.style.border = "0px";
shim.style.position = "absolute";
if (s.zIndex !== null) {
shim.style.zIndex = s.zIndex;
}
shim.style.height = prop(s.height,"100%");
shim.style.width = prop(s.width,"100%");
shim.style.left = prop(s.left,"0");
shim.style.top = prop(s.top,"0");
return shim;
}
return this.each(function() {
if ( $('> iframe.bgiframe', this).length ==
0 ) {
if (s.mask) {
this.insertBefore(createMask(s,cn),
this.firstChild);
}
this.insertBefore( createShim(),
this.firstChild );
}
});
}
return this;
};

I think I got all the bits you need - but if there's anything missing
you should be able to find it at http://replayroutes.com/site.html.

Note that using this you can say $(my-elements).bgiFrame() to add the
shims to any set of elements. You can use $.bgiFrame("fix") to remove/
re-insert all the iframes (this is needed in FF if you have created
them before showing the earth instance - I just do it routinely
whenever I show the earth-view, just to be safe).

You can also say "$.ui.dialog.defaults.bgiframe = true;" to
automatically add shims to all jquery-ui dialogs.

Looking at it, you might also want/need:

if ($.browser.msie) {
debug("Patching mouseUp/mouseDown");
var orig_mouseUp = $.ui.mouse._mouseUp;
var orig_mouseDown = $.ui.mouse._mouseDown;
$.ui.draggable.prototype._mouseUp = $.ui.mouse._mouseUp =
function(e) {
debug("releaseCapture");
document.body.releaseCapture();
$(document.body)
.unbind('mousemove.'+this.widgetName,
this._mouseMoveDelegate)
.unbind('mouseup.'+this.widgetName,
this._mouseUpDelegate);
return orig_mouseUp.call(this, e);
};
$.ui.draggable.prototype._mouseDown =
$.ui.mouse._mouseDown = function(e) {
var eom = e.originalEvent &&
e.originalEvent.mouseHandled;
var ret = orig_mouseDown.call(this, e);
if (!eom && e.originalEvent.mouseHandled) {
debug("setCapture");
document.body.setCapture();
$(document.body)
.bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
.bind('mouseup.'+this.widgetName, this._mouseUpDelegate);
}
return ret;
};
}

$.each("draggable,resizable".split(","), function() {
var type = this;
$.ui.plugin.add(type, "iframeMask", {
start: function(event, ui) {
var o = $(this).data(type).options;
if ($(o.iframeMask === true ? "iframe" : o.iframeMask,
this.parent()).length) {
$('<div class="ui-'+type+'-iframeMask" style="background:
#fff;"></div>')
.css({
width: "100%", height: "100%", top: 0, left : 0,
position: "absolute", opacity: "0.001", zIndex: 1000
})
.appendTo(this.parent());
};
},
stop: function(event, ui) {
$("div.ui-"+type+"-iframeMask", this.parent
()).remove()
}
});

$.ui[this].defaults.iframeMask = true;
});

Without this, dragging and resizing objects (using jquery-ui's
draggable and resizable) has various issues.

Mark

Nymor

unread,
Dec 21, 2009, 3:59:52 PM12/21/09
to KML Developer Support - Google Earth Plug-in
<-- head explodes ;)

I suspect that will take me some time to work out/absorb ... and I
thought I was doing so well to get a basic shim going while
understanding what was actually going on :(

The idea of using ui-dialogs instead of building div content by hand
looks interesting - as does your bgiframe function - but as I say it's
alot to absorb.

As and aside I'm using
$('#' + sh_id).draggable({ iframeFix: true, containment: 'parent' });
to sort the draggable side out - and I'd read that this wasn't
available for the resizeable so I was not going to allow resizing.

All-in-all that's one hell of post Mark - thanks

Nymor

Markw65

unread,
Dec 21, 2009, 4:46:50 PM12/21/09
to KML Developer Support - Google Earth Plug-in
On Dec 21, 12:59 pm, Nymor wrote:
> The idea of using ui-dialogs instead of building div content by hand
> looks interesting - as does your bgiframe function - but as I say it's
> alot to absorb.

The bgiFrame function works with hand built divs too - but you will
have to call it explicitly. The nice thing about dialog is that it
does it for you (if you set $.ui.dialog.default.bgiframe = true).

> As and aside I'm using
> $('#' + sh_id).draggable({ iframeFix: true, containment: 'parent' });
> to sort the draggable side out - and I'd read that this wasn't
> available for the resizeable so I was not going to allow resizing.

Right - my iframeMask is doing essentially what iframeFix was supposed
to do, but it does it for both draggable and resizable. I say
supposed, because iframeFix appears to be broken - or at least, it
makes too many assumptions about what your layout looks like - sorry,
its been a while since I wrote this code, and while I remember that
iframeFix didnt (always) work, I dont remember exactly why. But I do
remember that various other sources think its broken too - eg
ui.layout mentions it, and has its own workaround (but that is
ui.layout specific, where mine should work for any draggable/
resizable).

Mark

dorjee

unread,
Dec 22, 2009, 6:49:06 AM12/22/09
to KML Developer Support - Google Earth Plug-in
Mark, I note in your Replay Routes example that the little + buttons
do not react when mouse cursor is passing over. Is it (even for a
specialist like you) impossible to have cursor changing and tooltips
displayed when mouse cursor is passing over? If possible, could you
add what is necessary for these features from the full code I give
higher in this topic? Thanks.

Nymor

unread,
Dec 22, 2009, 12:47:04 PM12/22/09
to KML Developer Support - Google Earth Plug-in
Superb stuff Mark - this is greatly appreciated.

I'm slowly trying to get to grips with this - but it's a few levels
above my current abilities but always willing to learn.

As a test I took my first shimtest page
http://www.thekmz.co.uk/GEPlugin/test/shim_test1/shim_test_1.htm

and added your utilities as a separate js file (will add a fuller
credits section later with any links back to you that you'd like in
there) and changed things to use them.

http://www.thekmz.co.uk/GEPlugin/test/shim_test1/shim_test_2.htm

Everything seems to work the same, with the addition of the shimmed
div being resizable, in FF but in IE I get a object doesn't support
this method on the
$('#' + div2shim_id).bgiframe();
line. Don't know if you could point out where I might be going wrong?

If you do seperate your code out and post a demo I have no doubt it
will be extremely helpful to numpties like me.

I hope you don't mind me quizzing you some more - major karma points
are stacking up for you ;)

Regards
Nymor

Markw65

unread,
Dec 24, 2009, 12:53:55 PM12/24/09
to KML Developer Support - Google Earth Plug-in
Hi,

Im away from my normal setup, and cant really investigate... but I
think the problem is probably the call to "debug" that I had in there.
If you havent provided that function, it will fail (and its on an IE
only path - so FF doesnt try to call debug). Easiest fix is to just
remove the call.

Mark

On Dec 22, 9:47 am, Nymor wrote:
> Superb stuff Mark - this is greatly appreciated.
>
> I'm slowly trying to get to grips with this - but it's a few levels
> above my current abilities but always willing to learn.
>
> As a test I took my first shimtest pagehttp://www.thekmz.co.uk/GEPlugin/test/shim_test1/shim_test_1.htm

Markw65

unread,
Dec 24, 2009, 12:54:52 PM12/24/09
to KML Developer Support - Google Earth Plug-in
It seems to work for me - the cursor changes from the hand as set by
GE to an arrow.

Which browser, and what page exactly are you seeing the problem with?

Mark

Nymor

unread,
Jan 6, 2010, 10:19:56 AM1/6/10
to KML Developer Support - Google Earth Plug-in
Hi Mark,

Sorry for the delay in getting back - Christmas/New Year and all. Hope
you had a good one :)

Can't quite remember what was what but seem to remember that removing
the debug did work.

I've been playing around with various options - using your bgiframe
code - trying to create my own shims etc - but there always seems to
be a problem somewhere along the line.

However I do like the Dialog route and if I can get the IE issues I
have with that sorted out it would be my preferred route as it seems
the most stable.

What I've done is create a simple test page
http://www.thekmz.co.uk/GEPlugin/test/shim_test2/shim_test_1.htm
that puts a Dialog above GE.

It uses $.ui.dialog.defaults.bgiframe = true; and your bgiframe and
draggable/resizable code (within jquery_utilities_mw.js)

Everything seems fine in FF but in IE there are a couple of issues
which I'm hoping you may be able to help with?

The righthand border of the dialog doesn't "shim". If you drag the
dialog off GE it's there but disappears when over the GE pane. (I also
found that if I had multiple dialogs only the top of the second one
showed until it was clicked/dragged).

Also the resizing seems a bit dodgy in IE. Sometimes when resizing (be
that right, bottom or corner) no matter which way I went the dialog
would just get smaller by x pixels.

(As an aside I've put the whole structure within a ui-layout as it
would be ideal to be able to contain the dialogs within the central
pane - although that's not a necessity. I managed to do that with my
home-rolled shims but they lacked in other areas that your approach
fixes)

Hope whatever is going funny is easliy solvable as I quite like this
method for it's simplicity.

Kindest regards
Nymor

Markw65

unread,
Jan 6, 2010, 11:51:33 AM1/6/10
to KML Developer Support - Google Earth Plug-in
Hi Nymor,

On Jan 6, 7:19 am, Nymor wrote:
>
> Hope whatever is going funny is easliy solvable as I quite like this
> method for it's simplicity.

Im sure its solvable, and that it will be easy once we've figured it
out :-)

On my site, the dialogs dont lose the right hand side in IE. So not
sure what's causing that. It might be an inherited style (eg border/
padding/margin affecting where the iframe ends), but I took quick look
and didnt see anything obvious.

Last time I worked on it, resize /did/ work on my site, but just tried
again, and its failing (more or less) the same way as yours. This is
supposed to be fixed by a combination of the setCapture/releaseCapture
code, and the $.ui.plugin.add(...,"iframeMask") code.

The setCapture/releaseCapture are there to ensure that the mousemove/
mouseup events keep getting sent to the $.resizable, even when the
mouse is over the geplugin (normally, geplugin would capture all mouse
events when the mouse is over it).

The other issue is that if the mouse wanders over an iframe with
nothing in front of it then mouse events start going to /that/ rather
than the window containing the iframe. Thats where iframeMask comes
in. It puts an almost transparent div over everything with zIndex
1000. This means that mouse events go to it, rather than to any iframe
that happens to be behind it. You might think the ideal solution would
be to create the iframe shims, together with an almost transparent div
right in front of them. I tried that, and it seemed to work - but then
clicks on flash objects get caught by the div (even if the div is
"behind" the flash object). So it looks like the best solution is to
create the mask just when its needed; ie, during resizing and
dragging.

As I said, I got all this working at one point, but I think I must
have changed something (or the gePlugin has changed) causing it to
break.

I'll look into it as soon as I get a chance. Note that my PWC based
solution still works nicely, and its essentially doing the same thing
(although its easier to see whats going on there, because the mouse
event handling is explicit - with jquery-ui its all hidden behind many
layers of abstraction).

One other point - your jquery_utilities_mw.js file really needs to be
wrapped in:

(function() {
...
)();

The way you've done it now, its putting a number of variables/
functions onto the window object (eg "prop", "createMask",
"orig_mouseUp" etc). If another library (or your code) defines "var
prop" for example at file scope, the bgiframe code will stop working
mysteriously...

Mark

Nymor

unread,
Jan 6, 2010, 10:17:22 PM1/6/10
to KML Developer Support - Google Earth Plug-in
Hi,

> Im sure its solvable, and that it will be easy once we've figured it
> out :-)

I hope so - as I say I really like this solution. If only everyone
used FF..


> On my site, the dialogs dont lose the right hand side in IE. So not
> sure what's causing that. It might be an inherited style (eg border/
> padding/margin affecting where the iframe ends), but I took quick look
> and didnt see anything obvious.

My test is a simple as it comes I think. A small style sheet with
stuff for the map3d div and a standard, unaltered, jquery-ui css. (Any
changes I make in my Live enviroment I do as !importants in my own css
rather than changing the themeroller ones).

While my js/css is getting better I'm a bit lost on what I should be
looking to help fix this - IE isn't as easy to debug as FF - but
anything I can do to help out I'm obviously more than happy to put in
the time.


> Last time I worked on it, resize /did/ work on my site, but just tried
> again, and its failing (more or less) the same way as yours. This is
> supposed to be fixed by a combination of the setCapture/releaseCapture
> code, and the $.ui.plugin.add(...,"iframeMask") code.
>
> ...
>
> As I said, I got all this working at one point, but I think I must
> have changed something (or the gePlugin has changed) causing it to
> break.
>
> I'll look into it as soon as I get a chance. Note that my PWC based
> solution still works nicely, and its essentially doing the same thing
> (although its easier to see whats going on there, because the mouse
> event handling is explicit - with jquery-ui its all hidden behind many
> layers of abstraction).

It's good, or bad as the case may be, that you get the same(ish)
problem. Would be great to get a fix. I tend to use non-resizable
anyway but would probably find a use when it's there. I did look at
the PWC windows but find jQuery confusing enough ;)


> One other point - your jquery_utilities_mw.js file really needs to be
> wrapped in:
>
> (function() {
> ...
> )();

Thanks - done.


Thanks again for your time on this - very much appreciated - I owe you
several beers (a few dozen + I think).

Kindest regards
Nymor

Markw65

unread,
Jan 7, 2010, 11:31:56 AM1/7/10
to KML Developer Support - Google Earth Plug-in
> > On my site, the dialogs dont lose the right hand side in IE. So not
> > sure what's causing that. It might be an inherited style (eg border/
> > padding/margin affecting where the iframe ends), but I took quick look
> > and didnt see anything obvious.
>
> My test is a simple as it comes I think. A small style sheet with
> stuff for the map3d div and a standard, unaltered, jquery-ui css. (Any
> changes I make in my Live enviroment I do as !importants in my own css
> rather than changing the themeroller ones).

Looking at the page in IE8, I see a new issue. When the page first
draws, the iframe is only a couple of pixels high (even though its
style is set to "height:100%"). If you click on the bit of the title
bar thats visible, the iframe suddenly jumps to full size (or at
least, almost full size).

Then using the built in developer tools, I can look at the layout of
the container div (ie the "dialog"), and the iframe, and see that the
iframe is a bit narrower, and a bit shorter than the div.

If I manually set the padding on the div to 0, it seems to fix the
width issue, but not the height. On the other hand, I dont seem to
have done that on my site...

By the way, for debugging IE issues, if you have ie8 it has a built in
debugger, with a lot of the facilities of firebug.

For ie6 and ie7 you can get the developper toolbar
http://www.microsoft.com/downloads/details.aspx?familyid=e59c3964-672d-4511-bb3e-2d5e1db91038&displaylang=en
which has all of the "inspection" capabilities, but no debugger; and
you can get the script debugger here:
http://www.microsoft.com/downloads/details.aspx?FamilyID=2f465be0-94fd-4569-b3c4-dffdf19ccd99&displaylang=en

Finally, if you want ie6, ie7 and ie8 all installed on one machine,
you can get VirtualPC images from here:
http://www.microsoft.com/downloads/details.aspx?FamilyId=21EABB90-958F-4B64-B5F1-73D0A413C8EF&displaylang=en.
Clunky, but it works...

Anyway, I'll look into the resize issue once I get time (probably at
the w/e); meanwhile, the "right hand edge" problem does seem to have /
something/ to do with your css (even if its something that /isnt/ in
your css). One thing I've taken to doing on all my sites is setting
border/padding/margin to 0 on both the html and body elements of the
page; mainly to avoid differences between the browsers when the
content is "height:100%;width:100%" - but Im wondering if that may be
getting inherited and affecting the iframe size...

Mark

Nymor

unread,
Jan 7, 2010, 5:09:38 PM1/7/10
to KML Developer Support - Google Earth Plug-in
Cheers Mark,

Changed my test page to set border,margin,padding on body,html to 0 -
no effect unfortunately.

Also got rid of the extra, unneeded, outer ui-layout wrapper and
removed everything else I thought was redundant.

Next is to strip the ui css down to the bear essentials - just the
dialog css - and see what part of that may be causeing this right-side
missing bit.

Thanks for the other info also.

Nymor

dorjee

unread,
Jan 8, 2010, 6:57:13 AM1/8/10
to KML Developer Support - Google Earth Plug-in
Cheers Mark,

I see the thread I launched is very active. But, Mark, do you have a
solution in mind concerning the overlay solution to display a button?
I can display a working button (it allows to download a kml file) but
I would like that the mouse cursor over the button generates a cursor
icon changing and/or a tooltip/hint display. I give you an example of
file here, the blue button is top/left:

http://www.panoramearth.com/earth/IuzDiH93oAQ.html

Thanks in advance
Dorjee

On Jan 7, 5:31 pm, Markw65 wrote:
> > > On my site, the dialogs dont lose the right hand side in IE. So not
> > > sure what's causing that. It might be an inherited style (eg border/
> > > padding/margin affecting where the iframe ends), but I took quick look
> > > and didnt see anything obvious.
>
> > My test is a simple as it comes I think. A small style sheet with
> > stuff for the map3d div and a standard, unaltered, jquery-ui css. (Any
> > changes I make in my Live enviroment I do as !importants in my own css
> > rather than changing the themeroller ones).
>
> Looking at the page in IE8, I see a new issue. When the page first
> draws, the iframe is only a couple of pixels high (even though its
> style is set to "height:100%"). If you click on the bit of the title
> bar thats visible, the iframe suddenly jumps to full size (or at
> least, almost full size).
>
> Then using the built in developer tools, I can look at the layout of
> the container div (ie the "dialog"), and the iframe, and see that the
> iframe is a bit narrower, and a bit shorter than the div.
>
> If I manually set the padding on the div to 0, it seems to fix the
> width issue, but not the height. On the other hand, I dont seem to
> have done that on my site...
>
> By the way, for debugging IE issues, if you have ie8 it has a built in
> debugger, with a lot of the facilities of firebug.
>
> For ie6 and ie7 you can get the developper toolbarhttp://www.microsoft.com/downloads/details.aspx?familyid=e59c3964-672...
> which has all of the "inspection" capabilities, but no debugger; and
> you can get the script debugger here:http://www.microsoft.com/downloads/details.aspx?FamilyID=2f465be0-94f...
>
> Finally, if you want ie6, ie7 and ie8 all installed on one machine,
> you can get VirtualPC images from here:http://www.microsoft.com/downloads/details.aspx?FamilyId=21EABB90-958....

Markw65

unread,
Jan 8, 2010, 10:33:48 AM1/8/10
to KML Developer Support - Google Earth Plug-in
My solution is to use iframe shims, and real html - it works, really!

If I wanted the outline to be more complex than a rounded corner
rectangle, I would use a screenoverlay for the "outside" parts, and
have an iframe in the middle (this is actually how the geplugin
implements balloons - a screenoverlay image for the border, and then
html in an iframe for the content).

Mark

Nymor

unread,
Jan 10, 2010, 12:04:20 PM1/10/10
to KML Developer Support - Google Earth Plug-in
> Looking at the page in IE8, I see a new issue. When the page first
> draws, the iframe is only a couple of pixels high (even though its
> style is set to "height:100%"). If you click on the bit of the title
> bar thats visible, the iframe suddenly jumps to full size (or at
> least, almost full size).


Hi Mark,

While I didn't seem to get this problem on my test page and do get it
in my dev environment. (That's a bit more complex with various
additional plugins and more complex layout). I found that if I set the
height of the Dialog again after I'd opened it it goes to full size.

do stuff...
$("#dlg_video").dialog('open');
$("#dlg_video").dialog('option', 'height', dv_size.height);

(I'm using height in px as I'm putting a JW Player video in there and
am sizing it to the size of the video)

I'd don't know if that gives any clue to what's going on?

Nymor

Markw65

unread,
Jan 12, 2010, 2:42:57 PM1/12/10
to KML Developer Support - Google Earth Plug-in
Hi Nymor,

The problem with the edge of the dialog disappearing is down to IE
running in Quirks mode.

In quirks mode, if an outer element has padding, and the inner element
has width or height specified as a percentage, the percentage is
relative to the size of the parent /minus/ the padding, where
according to the standard it should be relative to the size of the
parent.

The jquery-ui css causes the outer div of the dialog to have padding:
0.2em, and so, in quirks mode, the iframe is 0.4em smaller (in both
directions) than the div. Its positioned correctly (ie at the top
left), so the missing bits are at the bottom right.

You can easily fix it by changing the DOCTYPE:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://
www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

is what I use.

By the way, another useful header I use is:

<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />

This causes IE8 to behave like IE7 (and the emulation is pretty good,
as far as I can see - right down to the bugs).

In a way thats a shame, because for the most part IE8 is more
standards compliant. But IE8 introduces yet more strangeness (eg
certain display:none elements have non-zero width and height, which
confuses jQuery in various ways). Also, a lot of workarounds for "ie"
problems actually break IE8 (because it does the right thing to start
with!)...

So, for the most part, Ive found it better to use the header, and only
have to worry about IE6 and IE7, since I have to support those
anyway :-(

Mark

Markw65

unread,
Jan 12, 2010, 3:33:17 PM1/12/10
to KML Developer Support - Google Earth Plug-in
The resizable problem was just that I'd not patched the resizable
mouseUp/mouseDown functions (in the "if ($.browser.msie) {" code at
the top).

The patch is the same as for draggable (basically, use setCapture/
releaseCapture to ensure that we keep getting mouse events over the
geplugin), so I've changed that code to just patch $.ui.mouse._mouse
[Up/Down], and then assign to the draggable/resizable variants inside
the $.each loop below.

Seems to work nicely.

I've also done a little more cleanup on jquery_utilities_mw.js
($.bgiframe.defaults can now be used to set default values for
bgiframe), and I've used the "local $ trick", so it works even when $ !
== jQuery.

You can see the results here: http://maps.myosotissp.com/demos/popups2/index.html

There is still one small issue (IE only). When the window first
appears, the iframe is the correct size. But if you drag or resize the
dialog, the iframe ends up a few pixels too short vertically. If you
drag/resize again, it jumps back to its correct size for the duration
of the drag/resize - but then reverts to being too short when you
release the mouse. I'll investigate a little more...

Mark

Nymor

unread,
Jan 15, 2010, 3:14:53 PM1/15/10
to KML Developer Support - Google Earth Plug-in
Looking good Mark :)

Resizing works well in IE8 now and it also seems the dialog is not
clipped on the right hand side. The dialog doesn't pop-up in IE6
though? - not sure about IE7 as I don't have that installed anywhere.

Thanks again for this - and your stuff on jqGrid - haven't upped to
3.6 yet on that but see that you had massive input on that version - a
true hero :)

Regards
Nymor

Markw65

unread,
Jan 15, 2010, 6:37:17 PM1/15/10
to KML Developer Support - Google Earth Plug-in


On Jan 15, 12:14 pm, Nymor wrote:

> Resizing works well in IE8 now and it also seems the dialog is not
> clipped on the right hand side. The dialog doesn't pop-up in IE6
> though? - not sure about IE7 as I don't have that installed anywhere.

IE7 is fine, but there's definitely an issue with IE6.

The dialog is there, but hidden (try reducing the height of the
window, so that the dialog sticks out above and below the earth
instance).

Once you can "see" a bit of it, either dragging it, or resizing it
fixes the problem.

The problem turns out to be that the iframe height is zero (even
though its set to height:100%). And the "reason" for that is that the
outer div of the dialog has height:auto. I say "reason" because it /
shouldnt/ behave that way, but it does.

So the simplest fix is to set the initial height explicitly:

var root = $("#dialog_test").closest('.ui-dialog');
root.height(root.height());

Thats right, set the height of the dialog to the height of the
dialog :-)

Or at least, to the /computed/ height of the dialog.

Ive put up demos/popups3/index.html with the change.

I'd like to find a good fix in the bgiframe library - but its hard to
see exactly what to do there...

Mark

Markw65

unread,
Jan 16, 2010, 9:14:48 AM1/16/10
to KML Developer Support - Google Earth Plug-in
On Jan 15, 3:37 pm, Markw65 wrote:
>
> I'd like to find a good fix in the bgiframe library - but its hard to
> see exactly what to do there...

Ok, so the solution seems to be IE dynamic properties.

Basically, set the height/width of the div to the parent's computed
height/width.

To do this, I've included some conditional css in index.html (for
iframe.bgiframe, and div.bgiframe-mask), and I've modified createShim,
and createMask to not set height/width.

Ideally, I would have used setExpression to set the dynamic
properties, and then jquery_utilities_mw.js would not have required
the external css (you can see the call commented out in the code). The
trouble is, when I did that, the properties didnt update (even when I
called document.recalc(true)). Perhaps someone who understands dynamic
properties better than I do could figure out the correct way to set
the expression programatically...

With those changes, IE6 worked perfectly. But IE7 still had a problem
with the height of the iframe. It was fine when the dialog first
appeared, but after dragging/resizing the dialog, the iframe ended up
a few pixels short. I think that the issue (again) is that the outer
div of the dialog starts off with height:auto, but once you drag, or
resize it, it ends up with height:<actual-height>. And thats confusing
IE7 in some way...

So the fix to that was to enable the dynamic properties for both ie6
and ie7. ie8 doesnt support them except in backward compatibility
mode, and doesnt seem to need them either. I guess the issue here is
going to be that IE8 running in ie7 mode will still have the missing
pixels at the bottom...

I also did a bit of cleanup elsewhere. Rather than patching _mouseUp
and _mouseDown on $.ui.mouse, $.ui.draggable and $.ui.resizable, I
just put the relevant code into the iframeMask start/stop handlers.

Final (I hope) version at http://maps.myosotissp.com/demos/popups4/index.html

Like I said, easy once you know how :-)

Mark

Markw65

unread,
Jan 17, 2010, 2:12:59 PM1/17/10
to KML Developer Support - Google Earth Plug-in


On Jan 16, 6:14 am, Markw65 wrote:
>
> Final (I hope) version athttp://maps.myosotissp.com/demos/popups4/index.html

I lied. Here's the final version: http://maps.myosotissp.com/demos/popups5/index.html

I've switched to using a generated stylesheet for the default iframe
layout (ie fill the object its shimming). So you dont need the "ie6/7
only" stylesheet in your document anymore. It also means that you
could use your own stylesheets to override the defaults (rather than
having to explicitly set the styles on the iframe object itself).

I also detect the case of ie8 running in ie7 mode, and enable the
dynamic properties for that too (otherwise we lose a few pixels at the
bottom of the iframe).

Right now, I've verified that everything works in ie6/7/8, FF3.0/3.5,
Chrome 4.0

I would expect it to work in all versions of FF and Chrome that
support the GEPlugin.

Mark

Nymor

unread,
Jan 22, 2010, 6:51:14 PM1/22/10
to KML Developer Support - Google Earth Plug-in
Cheers again Mark,

This all seems to work well however a friend has told me that in my
dev implementation he only sees a white box when he views my site on a
MAC.

I don't know whether this due to the extra layers etc I've added - a
JW Player video in a wrapper div within the dialog content or not
(he's not even seeing the dialog header so I guess it might be a
general problem) but I've sent him your link page above to see whether
he sees the dialog pop-up in that + asked what MAC OS and browser he's
using.

I appreciate you didn't say you'd looked at this on a MAC and I hope
if there is an issue on that platform that it's solvable.

While I await this guys response can someone on a MAC do me a favour
and try Mark's latest page above and say what they see - white box or
dialog? - and if it's not working right are there any MAC based
developers out there who can help out with any ideas.

Much appreciated

Regards
Nymor

Markw65

unread,
Jan 22, 2010, 8:54:39 PM1/22/10
to KML Developer Support - Google Earth Plug-in
I actually have looked at it on a mac in the last few days, and it
seems to work perfectly for me - although I've only tried Firefox.
I'll try chrome & safari next time I get a chance and report back.

Mark

Nymor

unread,
Jan 22, 2010, 9:41:35 PM1/22/10
to KML Developer Support - Google Earth Plug-in
Cheers Mark :)

I've also sent my friend these 2 demo links also to try

http://www.thekmz.co.uk/GEPlugin/test/video_dialog/vdialog_2.htm
Basic JW Player inside pop-up dialog
&

http://www.thekmz.co.uk/GEPlugin/test/video_dialog/vdialog_3.htm
Simialr to the above but with a bit more "messing about" that I do
prior to showing the video in my real dev app (css and a slightly
different way/order of creating the swobject).

Hopefully you get to see those on a MAC (when you're next there) as
they appear in FF on Windows.

Your time as always is greatly appreciated.

Thanks
Nymor


Markw65

unread,
Jan 22, 2010, 10:50:11 PM1/22/10
to KML Developer Support - Google Earth Plug-in
Ok - so both links work in FF and Safari 4 for me. Chrome isnt yet
supported on the mac.

Mark

Nymor

unread,
Jan 23, 2010, 12:57:27 AM1/23/10
to KML Developer Support - Google Earth Plug-in
Thnaks Mark,

I'll see what my friend says - whether he can see them and go from
there.

Regards
Nymor

Nymor

unread,
Jan 24, 2010, 6:33:53 PM1/24/10
to KML Developer Support - Google Earth Plug-in
A bit more info from my friend...

We used your popups5 page so as not to confuse anything I may have
added in mine and he reports that the dialog initially pops-up but
them disappears behind GE leaving just the iframe part (I assume) as a
white box.

He uses OSX 10.4.11 with Safari 4.0.4 & FireFox 3.5.7.

He sent me a FireBug screenshot and I can't see anything that untoward
in it.

Strange?

Nymor
Reply all
Reply to author
Forward
0 new messages