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 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 today. 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 foo.bar ... js returns the value of foo.bar. edbrowse sets foo.bar = 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 frame, 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. Wow! 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 foo.bar, 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