HTML to PDF / DOCX / RTF Java converter library › Forums › PD4ML Forums › Technical questions / Troubleshooting › CSS selector parts using :last-child / :last-of-type seem to get ignored
- This topic has 3 replies, 2 voices, and was last updated Jun 14, 2023
14:49:53 by PD4ML.
-
AuthorPosts
-
May 24, 2023 at 17:08#36520
Hello,
another glitch we seem to notice: when we try to use :after pseudoelements on elements using :last-child / :last-of-type or negations thereof, the result is that:
– all elements, including the last element match the negation
– none matches the :last-child or :last-of-type<style type="text/css"> .mainwrapper > div:not(:last-of-type):after { content: '|' } .mainwrapper > div::last-of-type:after { content: '<' } .mainwrapper > div:not(:last-of-type) > span:after { content: '>' } </style> <div class="mainwrapper"> <div>Text start <span>(inner)</span></div> <div>Text middle <span>(inner)</span></div> <div>Text last <span>(inner)</span></div> </div>
Are these selectors be supported in principle?
Thank you
ViktorJune 1, 2023 at 00:04#36555I’m afraid that
:last-child
and:last-of-type
won’t be supported without a complete refactoring of the CSS runtime.Support requires either an additional parsing pass of entire HTML document, or non-trivial look-ahead parsing logic (in extreme cases, it takes even more time/resources than a second parsing pass).
All our attempts to implement this feature resulted in significant performance degradation even in simple cases where this feature was not used. We have decided to temporarily omit the feature
June 13, 2023 at 14:29#36615Thank you for your response.
Since last-child selectors are an important part of modernish CSS, we would appreciate if it could be done.
If PD4ML evaluating the entire document on-the-fly so that it cannot check the neighboring elements readily or drop a flag on previous elements when further siblings are detected?
Thank you!
June 14, 2023 at 14:49#36617The implementation of the feature only outwardly looks simple.
In order to implement the complex selectors, the CSS runtime is implemented as a specialized state machine: an appearance of a new HTML element in the parsing stream pushes the event to all selectors (they may either refuse the event or to change the entire runtime state). A closing HTML tag pops to previous state. At any document parsing point we can request the runtime to generate a list of properties matches the current CSS runtime state. Actually it is done for every parsed HTML element and it defines the final document style.
The single-pass approach works well in most cases, but
:last-child / :last-of-type
creates problems for it because it cannot look ahead and determine if a particular tag is the last one or not. Keep in mind that:last-child / :last-of-type
can be combined with other conditions such asP[attr=value]:last-child
, so a quick HTML scan by tag name is not enough. Also, the actual “last child” could be at the end of a huge HTML document, megabytes away from the current parse point.All of our previous approaches to implementing
:last-child / :last-of-type
functions resulted in a significant performance degradation, drastic for large HTML and CSS documents. We’ve already tried to fork HTML and CSS parsers to check in idle run whether a particular element is the last one in terms of selector conditions; we tried to clone the CSS state with last=true and last=false and then remove the misguessed state. Both approaches did not match our acceptance criteria from performance perspective.We have not exhausted new ideas on how to implement the feature yet, but, I’m afraid, we will be able to return to them only closer to September
-
AuthorPosts
You must be logged in to reply to this topic.