Hi, On Fri, Dec 11, 2009 at 08:53:18PM +0100, Johannes Hofmann wrote:
Hi,
On Fri, Dec 11, 2009 at 07:46:33AM +0000, corvid wrote:
Here's the nightmarish hackery that I ended up with while getting show/hide to work on display:none.
There might be issues with the implementation - I need to look at it in more detail - but the result is pretty amazing!
Let me check your patch in detail...
bleh. But I realized it still won't work right for the case like <form action=...> <input type=text name=... value="something to right-click on"> <div style="display:none"> <textarea name=...> text </textarea> </div> </form> because I would have to start digging into display:none Textblocks in search of not-display:none form things, but then normally you don't want to display not-display:none things inside display:none...so...ummm... this is all a demonstration of what not to do. As for what _would_ be non-horrible, good question.
I suppose a way just to toggle whether display:none is obeyed at all might be nicer for us, albeit not for the user.
Ok, I understand your concerns now. It might be better to simply not create dw-widgets in the display:none case. At least we should try that option to see if it's simpler. My reasons are: * we would not pollute dw/* which is complex already. dw/* would not look at style.display at all. * as Tim mentioned, you can always switch off remote CSS to see display:none stuff. * it does not mean that elements with display:none would not be part of the DOM tree, as the DOM tree will be separate from the widget tree. I also understand now your's and Tim's concerns about the style pointer in struct Word. As soon as we start to modify styles in an existing widget tree we will get into trouble with all those pointers as we can't modify style objects in place. So I would propose to do display handling in html.cc. Then we can convert Doctree to a real DOM tree. With that in place we can come back to the style in struct Word issue. We might simply have a pointer to the corresponding DoctreeNode, which could hold the style. We might even drop the style sharing code then - but let's see. Here comes a simple example to demonstrate why I think DOM-tree and widget tree should be separate - and I suppose that this is what Sebastian also had in mind with his CSS plan. This piece of HTML: <html> <body> <ul> <li>foo</li> <li>ba<b>r</b></li> </ul> </body> </html> results in: DOM-Tree: Widget-Tree: ========= ============ html | body Textblock | | ul Textblock / \ / \ li li AlignedTextblock AlignedTextblock | b whereas: <html> <body> <ul> <li style="display: inline">foo</li> <li>ba<b>r</b></li> </ul> </body> </html> results in: DOM-Tree: Widget-Tree: ========= ============ html | body Textblock | | ul Textblock / \ | li li AlignedTextblock | b Cheers, Johannes
Johannes wrote:
Ok, I understand your concerns now. It might be better to simply not create dw-widgets in the display:none case. At least we should try that option to see if it's simpler. My reasons are:
* we would not pollute dw/* which is complex already. dw/* would not look at style.display at all. * as Tim mentioned, you can always switch off remote CSS to see display:none stuff. * it does not mean that elements with display:none would not be part of the DOM tree, as the DOM tree will be separate from the widget tree.
I also understand now your's and Tim's concerns about the style pointer in struct Word. As soon as we start to modify styles in an existing widget tree we will get into trouble with all those pointers as we can't modify style objects in place.
So I would propose to do display handling in html.cc.
Your suggestion seems quite sensible to me now :)
Then we can convert Doctree to a real DOM tree. With that in place we can come back to the style in struct Word issue. We might simply have a pointer to the corresponding DoctreeNode, which could hold the style. We might even drop the style sharing code then - but let's see.
Would dw/ understand the contents of DocTreeNodes?
On Sat, Dec 12, 2009 at 09:38:20PM +0000, corvid wrote:
Johannes wrote:
Ok, I understand your concerns now. It might be better to simply not create dw-widgets in the display:none case. At least we should try that option to see if it's simpler. My reasons are:
* we would not pollute dw/* which is complex already. dw/* would not look at style.display at all. * as Tim mentioned, you can always switch off remote CSS to see display:none stuff. * it does not mean that elements with display:none would not be part of the DOM tree, as the DOM tree will be separate from the widget tree.
I also understand now your's and Tim's concerns about the style pointer in struct Word. As soon as we start to modify styles in an existing widget tree we will get into trouble with all those pointers as we can't modify style objects in place.
So I would propose to do display handling in html.cc.
Your suggestion seems quite sensible to me now :)
Let's see :)
Then we can convert Doctree to a real DOM tree. With that in place we can come back to the style in struct Word issue. We might simply have a pointer to the corresponding DoctreeNode, which could hold the style. We might even drop the style sharing code then - but let's see.
Would dw/ understand the contents of DocTreeNodes?
Sorry, what I said was misleading. dw/ would not include doctree.hh. However we could have one style object per DocTreeNode and then all objects in the widget tree (widgets or struct Words) that correspond to that DocTreeNode could point to that single style object - which we could then modify in place. The main link between DocTree and widget tree would be the other way round. Each DocTreeNode would have a pointer to the widget that is responsible for displaying it - we might need further information like the word indices if a single widget displays multiple DocTreeNodes.
I am still uncertain whether doing the display:none handling in src/Html.cc is really superior. What I liked about corvid's approach is the simplicity of the changes. It did not really involve any fundamental changes. Furthermore, I think handling of hidden elements is generally better suited in dw/ because it's design-related. It would make the whole separation useless, if we mixed parsing code with complex evaluation-logic. Moreover, it should be possible to use the dw-stack completely independent from Dillo's parsing code. Otherwise, this isn't necessarily the case as the developer needs to implement hiding manually. We could also apply display:none to hidden form elements (what I've tried in my patch). This is an advantage because dw's focus is not only HTML and CSS. It should be usable for any other markup as well. Therefore, I'd propose to introduce a general 'hidden' attribute applicable to any element. In the parsing code, hidden HTML form fields are simply converted and internally represented by an ordinary text field which, however, is not displayed. I haven't done any benchmarks but I guess this approach is more efficient in terms of memory usage and rendering speed. It doesn't require to render the whole page repeatedly from scratch when hidden elements are made visible as only a flag needs to be set. It's not required to add new widgets to the dw-layout as with the other approach. As for big pages (HTML manuals with 2-5 MiB), otherwise it would imply that the entire dw-tree in memory is freed and then reallocated afterwards - just because one was made visible! Would the code be really shorter if done in src/Html.cc? I doubt that as we'd still need to check for the "display" value. Actually the patch doesn't do any more than that. So the benefits wouldn't be that striking. While I really like the idea of a DOM, I am somewhat concerned about the performance. A DOM is great when it comes to manipulating the design at runtime. It can be also useful for debugging purposes. However, as Dillo does not aim to support JavaScript there is virtually no need for a DOM. dw seems pretty flexible already and I guess it wouldn't be very difficult to do minor contents manipulation stuff. If understood your DocTree concept correctly, we won't end up with duplication as the DocTree represents both the contents and the style whereas dw only takes care about rendering, right? This sounds interesting but wouldn't it also mean that partial changes to the layout (or contents) would result in re-rendering the whole page? Therefore, I'd endorse the DocTree concept if there were some kind of 'change stack'. Changes can be 'reverted' and 'committed'. A commit then leads to only render the changes. (This idea might also come in handy with slow connections because we can make the 'commit'-rate dependent on the transfer speed. Thus, a 500 KiB website with 1 MiB/s will require only one 'commit' whereas with slower connections there might be more. How is this currently realized in Dillo, by the way?) --Tim
Hi Tim, On Sun, Dec 13, 2009 at 03:21:23AM +0100, Tim Nieradzik wrote:
I am still uncertain whether doing the display:none handling in src/Html.cc is really superior. What I liked about corvid's approach is the simplicity of the changes. It did not really involve any fundamental changes.
I'm not 100% sure yet either.
Furthermore, I think handling of hidden elements is generally better suited in dw/ because it's design-related. It would make the whole separation useless, if we mixed parsing code with complex evaluation-logic. Moreover, it should be possible to use the dw-stack completely independent from Dillo's parsing code. Otherwise, this isn't necessarily the case as the developer needs to implement hiding manually.
Well, I'm not sure if a independent widget library absolutely needs hiding / unhiding to be useful.
We could also apply display:none to hidden form elements (what I've tried in my patch). This is an advantage because dw's focus is not only HTML and CSS. It should be usable for any other markup as well. Therefore, I'd propose to introduce a general 'hidden' attribute applicable to any element. In the parsing code, hidden HTML form fields are simply converted and internally represented by an ordinary text field which, however, is not displayed.
I would agree if we would just have display:none and display:true or so. But to implement e.g. display:block, we need to add a new textblock or for tables we have to add a table widget. And this has to be done in html.cc as the complete structure of the widget tree is affected. But if we handle all values of display: other than "none" in html.cc, then why not handle "none" there as well? Also using display:none to hide form elements is a bit problematic, because then we loose the original value of display. When the user clicks "show hiddens", should we switch to display:block, or display:inline?
I haven't done any benchmarks but I guess this approach is more efficient in terms of memory usage and rendering speed. It doesn't require to render the whole page repeatedly from scratch when hidden elements are made visible as only a flag needs to be set. It's not required to add new widgets to the dw-layout as with the other approach. As for big pages (HTML manuals with 2-5 MiB), otherwise it would imply that the entire dw-tree in memory is freed and then reallocated afterwards - just because one was made visible!
For now we might simply not imlement a show display:none option. And for form elements we have it in place already. If we would implement changing the value of display: in place, then we would also have to support a change from e.g. inline to block. Additionally, I don't see a reason why we would have to through away the entire dw-tree in that case. We could just modify it in place and request a redraw.
Would the code be really shorter if done in src/Html.cc? I doubt that as we'd still need to check for the "display" value. Actually the patch doesn't do any more than that. So the benefits wouldn't be that striking.
While I really like the idea of a DOM, I am somewhat concerned about the performance. A DOM is great when it comes to manipulating the design at runtime. It can be also useful for debugging purposes. However, as Dillo does not aim to support JavaScript there is virtually no need for a DOM. dw seems pretty flexible already and I guess it wouldn't be very difficult to do minor contents manipulation stuff.
We already have a DOM tree - though a degenerated one. It is needed for CSS (see styleengine.cc and doctree.hh). It would be pretty simple to expand it to a real tree (it's a stack atm). As you said, this would be needed for manipulating the layout at runtime (e.g. for :hover), for CSS adjacent sibling matching, and for JavaScript.
If understood your DocTree concept correctly, we won't end up with duplication as the DocTree represents both the contents and the style whereas dw only takes care about rendering, right? This sounds interesting but wouldn't it also mean that partial changes to the layout (or contents) would result in re-rendering the whole page?
Therefore, I'd endorse the DocTree concept if there were some kind of 'change stack'. Changes can be 'reverted' and 'committed'. A commit then leads to only render the changes. (This idea might also come in handy with slow connections because we can make the 'commit'-rate dependent on the transfer speed. Thus, a 500 KiB website with 1 MiB/s will require only one 'commit' whereas with slower connections there might be more. How is this currently realized in Dillo, by the way?)
You can already modify the widget tree and only the modified stuff will be redrawn. It's implemented in dw/*. Cheers, Johannes
participants (3)
-
corvid@lavabit.com
-
Johannes.Hofmann@gmx.de
-
tim.nieradzik@gmx.de