Try:
<style>
p:hover:first-line { color: red }
</style>
<p>enough text to cause line wrapping should be here to illustrate first-line
style</p>
Note that :first-line style does not apply when the <p> gets hovered over.
If you add a non-dynamic style rule for :first-line, "p:first-line { color:
green }" then it works as expected.
The problem here is that the BlockFrame code is not looking for new :first-line
style contexts during ReResolveStyleContext. It needs to detect them and then
re-resolve children as appropriate.

OVERVIEW DESCRIPTION:
dynamically adding styles first-letter, first-line does not work
STEPS TO REPRODUCE:
1) Load the attachment
2[details][diff][review]) If text fits in one line, resize the window so that there is a line break
3) move the mouse over the text
ACTUAL RESULT:
text is in black
EXPECTED RESULT: first line of text is in red
BUILD DATE & PLATFORM: M7, 1999070917 build, Win32
ADDITIONAL INFORMATION: p:first-line {color:red} works; p:hover:first-line
{color:red} doesn't. For a more technical information, see peterl@netscape.com's
comment.
Changing bug status to "[TESTCASE] ..." standard.

Netscape's standard compliance QA team reorganised itself once again, so taking
remaining non-tables style bugs. Sorry about the spam. I tried to get this done
directly at the database level, but apparently that is "not easy because of the
shadow db", "plus it screws up the audit trail", so no can do...

This bug surfaces also in other situations: for example when JavaScript code assigns a new id or class to an existing tag, thus bringing such a tag under the scope of a :first-line or :first-letter CSS rule.
Attaching test-case for :first-line

Created attachment 221927[details]
Testcase showing that changing the class of an element applies new CSS rules excpet for :first-line
This testcase shows that when JavaScript changes the class of an element, that element takes over the new styling from the CSS, except for the rules concerning :first-line ; similar results are obtained by using :first-letter, or by changing the id and using id-specific CSS rules.

Created attachment 412154[details][diff][review]
patch
In the first-letter case, because we have the first letter style bit all we really need to do is set that bit and somehow make sure RecoverLetterFrames gets called on the block. Any ContentInserted on a child of the block would suffice, but I can't think of a way to make that work well. So I guess we just have to reconstruct the block.

Comment on attachment 412154[details][diff][review]
patch
Several issues here:
1) It might be better to deal with the styles going away by re-probing while reresolving those frames like we do for :before/:after. Not sure it actually is, though.
2) You need to add more conditions here, similar to the ones for :before/:after. Otherwise, various anonymous blocks that correspond to nodes that happen to have first-* style will trigger this... One issue is table cells. Do those get first-letter/first-line styling?
Also, shouldn't this check only happen for the first continuation?

(In reply to comment #33)
> (From update of attachment 412154[details][diff][review])
> Several issues here:
>
> 1) It might be better to deal with the styles going away by re-probing while
> reresolving those frames like we do for :before/:after. Not sure it actually
> is, though.
Seems like it would be a wash. But having the code for adding/removing together in one place seems like it would be a plus clarity-wise.
> 2) You need to add more conditions here, similar to the ones for
> :before/:after. Otherwise, various anonymous blocks that correspond to nodes
> that happen to have first-* style will trigger this... One issue is table
> cells. Do those get first-letter/first-line styling?http://mxr.mozilla.org/mozilla-central/source/layout/generic/nsBlockFrame.cpp#6331 says which anon boxes can have first-letter. With the exception of fieldsets (see http://mxr.mozilla.org/mozilla-central/source/layout/base/nsCSSFrameConstructor.cpp#9248), I would assume that first-line would be the same.
> Also, shouldn't this check only happen for the first continuation?
Ah, yes it should, the first-line check is only valid on the first continuation for one thing.

Hmm. That assert in blockframe actually looks like it might be wrong. Specifically, we allow first-letter/line on <html:button style="display: block">, it looks like... I wonder whether that's new or whether we've been doing it for a while.
It also looks like we might allow it for <select>; that's only saved by the fact that we typically have no inline kids of <select>. We should turn that off.
It also looks like we allow these styles on the block of an <svg:foreignobject>, which has a pseudo that's not in that assert's whitelist.

> Seems like it would be a wash. But having the code for adding/removing together
> in one place seems like it would be a plus clarity-wise.
It's not quite a wash in cases where there are lots of first-letters/first-lines, since in those cases we end up reresolving the style context for those pseudo-elements twice. But I think those cases are likely pretty rare.
Want to make that "do I have a first-line" check into a method we could reuse in the frame constructor where we currently probe for first-line stuff using styles?

Created attachment 413487[details][diff][review]
patch v3
This patch uses the frame tree check for first-line instead of probing for pseudo style in frame construction.
I made CanBeFirstLineContainer/CanBeFirstLetterContainer as complete as I can think of, including svg foreign objects, selects, and buttons.
I turned off special block styles for select frames, and call CanBeFirstLineContainer/CanBeFirstLetterContainer during frame construction so we don't try to construct first-letter/line in weird cases.
I realized that the "do I have a first-line" check had to be a bit more complicated to deal with the case of no leading inlines, and the only part that could be factored out is the "is first child a line frame with first-line pseudo style", but I didn't bother since it is just two lines. I can still factor it out if you'd like.
As in bug 484400, the first-letter tests can't use a fake first-letter styled span because they fail on Windows and Mac.

+ // We check if there is an existing first-line child. If there isn't
This is all a new optimization, right? Might be better to separate the optimization from the bug fix here. How sure are we that this is a worthwhile optimization?
+ nsIAtom* frameType = aFrame->GetType();
+
+ if (!(aMinChange & nsChangeHint_ReconstructFrame)) {
+ // Check if we need to reconstruct for added/removed first-letter style,
+ // but only on the first continuation of block frames.
+ if (frameType == nsGkAtoms::blockFrame &&
+ !aFrame->GetPrevContinuation()) {
+ nsBlockFrame* blockFrame = nsLayoutUtils::GetAsBlock(aFrame);
Instead of calling GetType here I'd just call GetAsBlock and check for null, hoisted out so we can reuse the result.
In nsFrameManager::ReResolveStyleContext I'm not sure whether we should check CanBeFirstLetterContainer on the block before we probe for pseudostyle and check NS_BLOCK_HAS_FIRST_LETTER_STYLE. Since most blocks can be first-letter containers (I guess) it's probably better to probe for first-letter first. Similar for first-line. And maybe refactor the code so that we just have NeedsReconstructionForFirstLetter/NeedsReconstructionForFirstLine helper functions?

Thoughts on part 2 (and related):
1) NS_BLOCK_FLAGS_MASK should just be fixed to exclude the bits we exclude in
nsBlockFrame::Init.
2) It'd be really nice if we could use flags to implement CanBeFirstContainer
(which CSSFC could then set to match what it thinks it's doing), but we only
have one free flag, right? Could use that one flag for everything except
fieldsets? Why are we not allowing first-letter on fieldsets anyway?
3) Just pass nsStyleContext* instead of the nsRefPtr ref to the static inlines
in the frame manager?

(In reply to Phoenix Enero from comment #59)
> Encountered this when I created a "dropcap" button in TinyMCE editor. Please
> fix (this bug is darn old.)
For those curious, I counteracted this by quickly hiding and showing the element with `display` to force styles refresh (this is achieved by using `setInterval`.)