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