After the release, I'd like to think about expanding frames automatically.
It's complicated so I'm asking your advice.

First, I don't want to do it at all.
Opening websites is slow already, how much slower if I automatically expand 
each frame before you can see the text?
And most of those frames I don't care about anyways, they are advertising or 
supplementary information.
I like the current paradigm, type exp if you want to expand a frame.
Most of them I never expand.
But ... as Kevin has discovered ... some of the acid tests, and perhaps some of 
the real world sites,
have javascript that assumes the frames are expanded.
They dip into the objects in those frames, and sometimes twiddle those objects.
So we have some choices here.

1. Don't expand the frames and just realize that some sites won't work properly.
Hopefully very few sites, hopefully it's just advertising or visual effects 
that don't run.
In other words do nothing, that's the easiest.

2. Expand each frame in the window.
I'd have to expand the frames first, then run the javascript for the main 
window, because the frames are suppose to be there.
As part of parsing html, aha, a <frame> tag, stop what you're doing and go 
expand that frame, then resume.
And that frame could contain another frame and so on.
All my html parsing and stacking has to be reentrant, and I'll bet it's not 
So a bit of work, and again, it's gonna slow down edbrowse, which is already 
pretty slow.

2A. All the frames probably fetch the same javascript files as the original 
window, it would be nice if I could just pull them from cache.
I know we already do this, but I mean don't even issue the head command.
Surely the javascript isn't going to change in the quarter second since I last 
fetched it.
Maybe this should be a general mechanism,
if you're fetching js, and it's in cache, and you accessed it less than one 
minute ago, then skip the head request and just grab the file.

3. Only as we need it.
I like this but it's the hardest to do.
Don't expand anything at the start.
Instead of a contentDocument object, each frame has a contentDocument getter 
and setter.
The getter returns the raw object content$Document if it is there, but if not, 
then the frame has not been expanded.
Expand the frame, link its document object to content$Document, then return 
content$Document as though it was there all the time.
Sweet, but watch what has to happen.

Think of it as a 2 process model, because the messaging is really the same even 
in one process.
The 2 processes are client server.
edbrowse asks for ... js returns the value of
edbrowse sets = 7 ... js acknowledges.
edbrowse says to run this javascript ... js runs it and returns the result.
It's a very direct protocol.
To do what I'm talking about, we have to stand it on its head.

edbrowse: run this script
js: from inside the content$Document getter, oh my goodness, we have to expand 
this frame, send a frame expand message back to edbrowse.
edbrowse is waiting for an acknowledgement or a result from the script, and now 
it gets a command.
It has to pause what it is doing, pushing things onto a stack of some sort,
and expand the frame, as though the user had typed exp at the keyboard.
Then it tells JS the frame is expanded, pops everything off the stack, and 
waits for the result of the script that it asked js to run earlier,
now in the state it was in before.
Awkward enough, but even more awkward on the js side.
It is in the middle of the getter, and it has to pause everything, push it onto 
a stack or something,
and go back to the main message loop, because edbrowse is expanding another 
and edbrowse is going to send all sorts of js requests to do that.
Eventually edbrowse will send along a frame-is-done message and js pops 
everything, goes back to the contentDocument getter,
and returns content$document.

There's another way that is easier.
Stay within the one process model.
Replace most of the messages with simple function calls.
I don't have to send a message to a js process, or virtual process, to find the 
value of, and wait for the value to come back as a message, I can just 
call the native function get_property_string_nat(foo, "bar");
There we go.
When js wants to expand a new frame it doesn't have to send a message the wrong 
way down a one way street.
It can just call the edbrowse parse and render mechanism as a function,
which calls more js routines, as functions, and C provides the stack.
I don't have to invent state stacks and use setjmp and longjmp, which I've done 
before but it's like playing with fire, I can let C take care of it.
This assumes duktape is reentrant, which it probably is.
I'm guessing that by the way you pass the context pointer to every duktape 
function call.
So yes that's good, but it locks us into the one process model.
I'd keep the 2 process model around, but this feature simply wouldn't work in 
the 2 process world.

That gives you something to ponder over the next week or so.

Karl Dahlke
Edbrowse-dev mailing list

Reply via email to