safari compatibility, drosera useless

T

Tom

I have an oo-type javascript program running perfectly on IE 6.0+, FF
1.5+, and Opera 7+ on Windows 98+, Linux (RH 9, FC 6), and Mac OS X.
4. As usual, the Safari browser is not working correctly, and because
it lacks an internal debugger, I'm completely unable to see what the
problem is.

So I downloaded that "Drosera" debugging program, but I'm finding it
useless for the following reasons:

1) I cannot "Attach" it to Safari 2.0 directly -- it only allows me to
attach it to this WebKit program, which looks like a Safari clone of
some kind?
2) My program works perfectly in WebKit and produces no errors! I
need to see the errors in Safari 2.0, not this WebKit build, whatever
it is.

You can see the script here:
http://www.biegeldesigns.com/projects/preload.php

People keep telling me to keep an open mind about Macs and web
development, but situations like these are infuriating, waste time,
and make me even more attached to Linux or even Windows.

Any help would be appreciated!
 
A

ASM

Tom a écrit :
I have an oo-type javascript program running perfectly on IE 6.0+, FF
1.5+, and Opera 7+ on Windows 98+, Linux (RH 9, FC 6), and Mac OS X.
4. As usual, the Safari browser is not working correctly, and because
it lacks an internal debugger, I'm completely unable to see what the
problem is.

Safari's console tells "undefined value" without other precision

Why do you use a so complicated code to do something quite simple ?

I'll pass on html with a table (that do not simplify JS actions)

<script type="text/javascript">
function init() {
I = document.images;
A = [];
postload(0,I.length);
}
function postload(k, max) {
if(k<max) {
A[k] = new Image();
A[k].onload = function() {
var o = I[k].parentNode.parentNode.parentNode;
o = o.getElementsByTagName('TD');
var m = o[1].getElementsByTagName('DIV')[0];
m.innerHTML = 'loaded';
m = o[0].getElementsByTagName('A')[0];
m.href = 'javascript:displayImage(A['+k+'].src);';
k++;
postload(k, max);
}
A[k].src = I[k].src.replace(/.tmb/,'');
}
}
function displayImage(what) {
var I = document.getElementById('image_full');
I = I.getElementsByTagName('TD')[0];
if(typeof(what)=='undefined' || !what ||
what.toString().indexOf('http')<0) {
I.innerHTML = 'Please wait complete loading !';
I.style.background = '';
}
else {
I.innerHTML = '&nbsp;';
I.style.background = 'url('+what+') no-repeat center center';
}
}
onload = init;
</script>

And it works fine with my Safari 1.3.2
as with my FF 2.0.1
or my Opera 9
and even with my IE 5.2 (Mac)

Without needing a list of big images,
using only urls of thumbnails.
(no need IDs of elements, except this of "viewer"
(that we haven't on your page ==> head hack in JS to reach it)
Most of the JS up there is to try to find and organize where things are
in the table :-(
You can see the script here:
http://www.biegeldesigns.com/projects/preload.php

Any help would be appreciated!

Try to use cleverly CSS instead of tables.

The first one could be :

<div id="thumbnails">
<dl>
<dt><a href="javascript:displayImage()">
<img src="....tmb.jpg" alt="thumbnali" title="" />
<a>
<dd></dd>
<dl>
<dl>
<dt><a href="javascript:displayImage()">
<img src="....tmb.jpg" alt="thumbnali" title="" />
<a>
<dd></dd>
<dl>
.... etc ...
</div>

And second one :

<div id="viewer">
I dare you to stop the preload sequence!
</div>
 
T

Tom

Thank you for your detailed reply, but the object-oriented method is
much more portable and flexible, and doesn't rely on all the string
literals present in the example page. I also don't feel I should have
to "downgrade" the javascript because of a DOM hole in Safari.

I've found another programmer who has the exact same problem I do:

http://www.thescripts.com/forum/thread451890.html

The fact that it works in WebKit AND Konqueror, but not the current
Safari release leads me to believe this is a bug unique to Safari.

Can anyone else confirm that when you assign the onload event handler
to an Image object in Safari, that the event object defaults to the
Window object, not the Image object as expected?

e.g.:

function Preload {
var thisImage = new Image() ;
thisImage.onload = Preload.prototype.onload;
thisImage.src = "whatever" ;
}
Preload.prototype.onload = function() {
alert(this) ;
}

// Safari will alert "object Window";
// all other browsers alert "object Image", or whatever variant the
browser returns, e.g. [object Image], [object] Image, etc.

Thanks


Tom a écrit :
I have an oo-type javascript program running perfectly on IE 6.0+, FF
1.5+, and Opera 7+ on Windows 98+, Linux (RH 9, FC 6), and Mac OS X.
4. As usual, the Safari browser is not working correctly, and because
it lacks an internal debugger, I'm completely unable to see what the
problem is.

Safari's console tells "undefined value" without other precision

Why do you use a so complicated code to do something quite simple ?

I'll pass on html with a table (that do not simplify JS actions)

<script type="text/javascript">
function init() {
I = document.images;
A = [];
postload(0,I.length);}

function postload(k, max) {
if(k<max) {
A[k] = new Image();
A[k].onload = function() {
var o = I[k].parentNode.parentNode.parentNode;
o = o.getElementsByTagName('TD');
var m = o[1].getElementsByTagName('DIV')[0];
m.innerHTML = 'loaded';
m = o[0].getElementsByTagName('A')[0];
m.href = 'javascript:displayImage(A['+k+'].src);';
k++;
postload(k, max);
}
A[k].src = I[k].src.replace(/.tmb/,'');
}}

function displayImage(what) {
var I = document.getElementById('image_full');
I = I.getElementsByTagName('TD')[0];
if(typeof(what)=='undefined' || !what ||
what.toString().indexOf('http')<0) {
I.innerHTML = 'Please wait complete loading !';
I.style.background = '';
}
else {
I.innerHTML = '&nbsp;';
I.style.background = 'url('+what+') no-repeat center center';
}}

onload = init;
</script>

And it works fine with my Safari 1.3.2
as with my FF 2.0.1
or my Opera 9
and even with my IE 5.2 (Mac)

Without needing a list of big images,
using only urls of thumbnails.
(no need IDs of elements, except this of "viewer"
(that we haven't on your page ==> head hack in JS to reach it)
Most of the JS up there is to try to find and organize where things are
in the table :-(
You can see the script here:
http://www.biegeldesigns.com/projects/preload.php
Any help would be appreciated!

Try to use cleverly CSS instead of tables.

The first one could be :

<div id="thumbnails">
<dl>
<dt><a href="javascript:displayImage()">
<img src="....tmb.jpg" alt="thumbnali" title="" />
<a>
<dd></dd>
<dl>
<dl>
<dt><a href="javascript:displayImage()">
<img src="....tmb.jpg" alt="thumbnali" title="" />
<a>
<dd></dd>
<dl>
... etc ...
</div>

And second one :

<div id="viewer">
I dare you to stop the preload sequence!
</div>
 
V

VK

// Safari will alert "object Window";
// all other browsers alert "object Image", or whatever variant the
browser returns, e.g. [object Image], [object] Image, etc.

Check maybe they didn't screw up on W3C model:

function imageLoadListener(e) {
window.alert(e.target);
window.alert(e.relatedTarget);
}

var img = new Image;
img.onload = imageLoadListener;
document.body.appendChild(img).src = 'some/URL';


btw I did not see you adding new images into document - though I may
missed it. You don't suppose to receive onload notifications right
from the browser cache, for "purely virtual" images. Neither browser
supposes to download and cache an image just because you created Image
object and set .src attribute for it. Some browsers do provide this
convenience out of their good heard but don't make any strong
assumptions in this regard.
 
R

RobG

Thank you for your detailed reply, but the object-oriented method is

Please don't top-post here. Reply below trimmed quotes.

much more portable and flexible, and doesn't rely on all the string
literals present in the example page. I also don't feel I should have
to "downgrade" the javascript because of a DOM hole in Safari.

Your example is not particularly "object oriented". The Preload
function makes a pretence at being a constructor, but it is used like
a plain function. Its prototype is used essentially as a namespace,
it isn't used for inheritance. You could achieve exactly the same
result with:

<script type="text/javascript">

var preload = (function(){
return {
img: function(src){
var img = new Image();
img.onload = this.onload;
img.src = src;
},
onload: function(){
alert('Dynamic: ' + this);
}
}
})();

preload.img('news.jpg');
</script>

<div id="xx">
<img src="news.jpg" onload="alert('Inline: ' + this);">
</div>

[...]
Can anyone else confirm that when you assign the onload event handler
to an Image object in Safari, that the event object defaults to the
Window object, not the Image object as expected?

The issue isn't the event object, it's that if you dynamically assign
an event handler to the object returned by new Image, it's this
keyword is set to the window object, not the image object.

It is rectified by creating an img element rather than an Image
object. In the above code, replace:

var img = new Image();

with

var img = document.createElement('img');

and all is well.
 
T

Tom

Image preloading is passé, I think it indicates poor design. Consider
loading the images in-line using normal HTML, then hide and show them
by tinkering with their CSS - visibility, display, z-index, whatever.

That should require less code and be easier to make cross-browser.

VK: To be honest, I had not even thought about browsers not loading
the image when given the src property -- I've tested this with
browsers that take up something like 99%+ of the usage shared,
according to W3Schools. Could you provide a name/version of a browser
that DOESN'T load the image when given a src attr?

RobG: I realize it's not an intended use of oo-javascript, but this
lib needs to be portable, and I want to avoid any chance of a third-
party developer accidentally redeclaring a function. Your example
solves the problem, but still does not explain why Safari acts in this
manner. It seems to me that in any oo-programming language, if you
create a new instance of a class (in this case, `Image`), and the
instance's `this` reference returns a DIFFERENT class name (in this
case, `Window`), there's no other explanation other than a bug. How
can one possibly justify returning a different class with the `this`
keyword? The fact that the more recent versions of WebKit act in line
with the other major browsers further leads me to believe that this is
just another Safari javascript problem.

I do agree with image preloading being out-of-date though. This is
for a freelance job though, so the client is the boss :)

Thank you again --
 
R

RobG

RobG: I realize it's not an intended use of oo-javascript, but this
lib needs to be portable, and I want to avoid any chance of a third-
party developer accidentally redeclaring a function. Your example
solves the problem, but still does not explain why Safari acts in this
manner. It seems to me that in any oo-programming language, if you
create a new instance of a class (in this case, `Image`), and the
instance's `this` reference returns a DIFFERENT class name (in this
case, `Window`), there's no other explanation other than a bug.

I think you are straying from the issue here. Javascript doesn't have
classes, it isn't a classic OO language - the closest thing it has to
classes are objects created by constructors. The this keyword of
constructed objects has nothing to do with their constructor, in fact
it is extremely unlikely that it will ever refer to the constructor.

The issue here is that when you assign a function reference to an
Image object's onload property, you expect the Image object to be
referenced by the function's this keyword when the load event occurs
and calls the function. Problem is, you don't know how the event
calls the function. It's just a convention, and is a bug in Safari in
so much as it doesn't follow that convention.

It may have been a better idea if functions called by event handlers
had their this keyword set to the event object.

How
can one possibly justify returning a different class with the `this`
keyword?

The ECMAScript specification is clear on how a function's this word is
set, and it has nothing at all to do with an object's "class".

The fact that the more recent versions of WebKit act in line
with the other major browsers further leads me to believe that this is
just another Safari javascript problem.

Great! I wasn't defending Safari's non-conformance, only the notion
that it was somehow contrary to a language or DOM specification.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top