Yann-Erwan Perio wrote:[color=blue]
> Richard Cornford wrote:[color=green]
>> Personally, I don't like the answer to 4.9 much anyway.[/color]
>
> After studying your script I can understand why indeed,
> the FAQ code uses too simplified a logic; I cannot tell
> to which extent this can be dangerous, though.[/color]
Code that is logically the same as the example in the FAQ has given me
the flickering scroll bar problem that I described. Clearly the FAQ code
cannot be an issue for most of the people using it, else it would have
attracted more comment in the past. But then it gives the
viewport/client-region dimensions on IE so maybe that is down to limited
cross-browser testing.
<snip>[color=blue]
> ... ; I have learnt things, especially with Opera, which
> I (naively) thought behaved the same way as Mozilla.[/color]
One of the problems with Opera 7 is that behaviour has changed with
progressive versions. I am not sure whether they are migrating toward
Mozilla-like, or IE-like, behaviour.
[color=blue][color=green]
>> For example, the real viewport/client-region dimensions
>> will never exceed the corresponding innerWidth/Height
>> dimensions (only the document dimensions can do that, though
>> they may not), and if a page is scrolled it is reasonable to
>> assume that it has a scroll bar, which means that in that
>> case the 'client' dimension inside the scroll bar must be
>> smaller than the corresponding 'innner' value.[/color]
>
> That's an excellent hypothesis,[/color]
As it stands, the algorithm used is about the third variant that I have
attempted to apply to the problem, and the most successful to date.
There may still be room for improvement, though just throwing in
additional test criteria may not be an improvement as that may slow down
the reading/reporting of the values by the interface, and I want that to
be as fast as possible.
[color=blue]
> which permits, with the ranking process, a finer approach;
> at least it is much more satisfying than the pure
> compatMode-based one (which relates the value of a property
> 'compatMode' to another 'dimensions' - that goes against
> good feature detection).[/color]
The compatMode test is not good feature detection. It is almost 'object
inference', except that the relationship is well documented for IE
browsers so there it is not that much of an inference. Indeed the code
in 4.9 doesn't use a compatMode test, though the code it does use makes
assumptions about the values of clientWidth/Height that are true for IE
but will fail horribly on some other browsers (which never execute that
code branch as others seem to universally support innerWidth/Height).
[color=blue][color=green]
>> This brings me to the progressively self re-configuring
>> ("Russian doll") object/system that I said I would
>> publish a few months back. That object was intended to
>> address this particular problem.[/color]
>
> I'm starting to see the interest of the technique from a
> conception point of view, beyond the simple init/replace
> issue. The resulting structure and flow are elegant and
> attractive, however it can easily turn to something
> complicated (it took me some time to figure out why your
> smart size getting didn't recurse forever); I wonder to
> which extent the russian doll pattern could be formally
> structured, using objects and setters.[/color]
Complexity is an issue, but I think that so long as it is internal to an
object/function that has a simple, cohesive interface then it is less of
a problem. At least so long as the code works as advertised and nobody
has to go in and fix it. Well designed cross-browser code should satisfy
that requirement as its logic should enable it to exhibit
planned/designed behaviour in any environment.
One of the reasons that I have been writing this type of functionality
as independent low-level interface objects is that the test-case pages
for a single interface can act as unit tests, and once properly tested I
can be confident that I have a unit of reliable, re-usable code that
_will_ exhibit planned/designed behaviour in any browser environment.
(It also means that when I can be certain that precise
viewport/client-region dimensions are not necessary, and
innerWidth/Height will be good enough, I can use an alternative
implementation of the same interface that employs the simpler
configuration/testing. Without having to alter a line of any code using
the interface.)
As to formally structuring the "Russian doll" pattern; I haven't
written/tested enough examples yet to be certain that I have a good
handle on the issues. Another couple of generations and it might be
worth writing up, and publishing, a description of the strategy.
Though I don't think I will want to connect the pattern exclusively with
objects and getters/setters, as a pattern where the global manifestation
is always no more than an identifier referring to a function object
(such as the compatModeTest function needed by getWindowState) seems
like a reasonable application as well.
I would encourage the use of low-level interface object, which mostly
will have getters and setters, but that represents a line of thought
that is simultaneous with (and will tend to employ) the "Russian doll"
pattern, rather than an integral part of the strategy itself.
<snip>[color=blue]
> I don't have Konqueror nor Mac browsers here,[/color]
If you have 4 or 5 hours use of a broadband connection (or better, for
less time) and a CD burner, then you might like to look into Knoppix
(<URL:
http://knoppix.com >). A Linux version designed for use from a
self-booting CD ROM (you download the ISO image of the disk (which is
why it takes some time (640Mb)), including KDE with whatever is the
latest version of Konqueror. The version I am using (3.6) has
successfully booted about 3 out of 4 of the x86 desktop PCs that I have
tried it on to date. I am also finding the when something works on
Konqueror 3 then it also tends to work on Mac Safari (though the reverse
probably isn't true).
[color=blue]
> but I've tested it on 'regular' browsers (IE4, IE5, IE5.5,
> IE6, NN4.8, Mozilla 1.8, Opera 6, Opera 7) and it gave the
> safest results for scripting; the logic behind the script
> is strong enough to make me confident it should behave
> correctly in other agents, provided they respect the
> inner/client hypothesis.[/color]
I am fairly sure that the logic is sound (I should have traced out all
of the possibilities by now) but I have been caught being over-confident
before so I am not going to claim it is safe to use until I have
finished testing it.
[color=blue][color=green]
>> function getScrlXTest(){hasChangedScroll();return getScrlXMain();}
>> function getScrlYTest(){hasChangedScroll();return lastSl;}[/color]
>
> One or the other is the same, lastSl is faster but getScrlYMain
> is easier to read.[/color]
The hasChangedScroll function is guaranteed to have called getScrlYMain
and assigned the current value to lastSl. I am interested in having the
interface methods return their results as quickly as possible so
returning lastSt from getScrlYTest avoids re-calling getScrlYMain but
the same cannot be done for getScrlXMain/lastSt as it might not have
been updated in the call to hasChangedScroll.
However, there is a minor mistake in this code, and in -
hasChangedScroll -, as it was my intention that the 'l' at the end of
lastSl represent 'left' (similarly the 't' in lastSt for 'top'), so the
two variables are being used the wrong way around here and the right way
around in the - initWidthHeight - function. That doesn't make much
difference in practice (both X and Y scrolls are likely to be zero on
first use anyway, and otherwise the error will just re-run the test
functions once), but it is still wrong and those two lines should be:-
function getScrlXTest(){hasChangedScroll();return getScrlXMain();}
function getScrlYTest(){hasChangedScroll();return lastSt;}
- with the - hasChangedScroll - function becoming:-
function hasChangedScroll(){
if(
(lastSt != (lastSt = getScrlYMain()))||
(lastSl != (lastSl = getScrlXMain()))
){
threeObjectTest();
}
}
(While writing this I was happy to observe that the algorithm for the
not-equals comparison allows for the comparison of current and last
values, along with the update to the single variable used, in one
expression.)
[color=blue][color=green]
>> OK that is a huge mass of (convoluted :) code, made
>> worse by being extensively commented.[/color]
>
> Ah I was thankful for these comments however! ...[/color]
Yes, it would hardly have been fair to ask anyone to look at it without
some comments. But ultimately the sensible way of dealing with the
shortcomings in 4.9 will be to do what was done for 4.15 and provide an
additional page which describes the issues and offers at least one
example of avoiding them. For which I will need a fully (probably more
fully) commented version.
[color=blue][color=green]
>> Comments/feedback/Improvements/etc welcome.[/color]
>
> A truly rich script, mixing an innovative approach to
> client dimensions measuring, and producing an advanced
> "russian doll" initialization; both areas definitely
> deserve further investigating.[/color]
Thank you, I look forward to seeing some implementations of self
re-configuring functions/objects of yours.
Richard.