Open Bug 45091 Opened 24 years ago Updated 2 years ago

::first-letter and openquote ::before should be together

Categories

(Core :: Layout: Block and Inline, defect, P3)

defect

Tracking

()

People

(Reporter: erik, Unassigned)

References

(Depends on 1 open bug)

Details

(Keywords: css1, css2, testcase, Whiteboard: [CSS1-2.3])

Attachments

(3 files, 4 obsolete files)

According to the CSS2 spec, :first-letter applies to any leading punctuation character as well as the first normal letter. The following test case used to cause a crash, but that was fixed. Now we need to make sure it works according to spec: http://bugzilla.mozilla.org/showattachment.cgi?attach_id=10091
Status: NEW → ASSIGNED
Target Milestone: --- → Future
remove Future for now.
Target Milestone: Future → ---
mark as moz1.0 for now.
Target Milestone: --- → mozilla1.0
erik resign. reassign all his bug to ftang for now.
Assignee: erik → ftang
Status: ASSIGNED → NEW
move to future for now.
Assignee: ftang → shanjian
Target Milestone: mozilla1.0 → Future
Status: NEW → ASSIGNED
so the :first-letter in this case should apply to the :before element? If that is what it is suppost to be then it WFM in build 2001100303 win32
ok I got it wrong. The bug still exist as the testcase needs to have :first-letter apply to the *S* too. So I assume the problem is that the open-quote is not reconized as a quote?
Keywords: css2
Keywords: css1
Whiteboard: [CSS1-2.3]
For anyone who looks: the problem is that, although :first-letter works properly for normal punctuation, it does not work for punctuation inserted using :before. I _think_ that the problem is that the :before node is separate from the text (there is a bug about :first-letter and image alt text, which I can't find at the moment, that I think is related).
I've started looking at this a bit. I'm unsure if what I'm doing is correct though. For exmaple, what should the frame tree look like for this case: <p><span>"</span><span>T</span>ext</p> CSS2.1 explicitly says that :first-letter is "innermost" which would mean: FL = p:first-letter <p><span><FL>"</FL></span><span><FL>T</FL></span>ext</p> Is this correct? then what about margins, borders and such?
Assignee: shanjian → block-and-inline
Severity: normal → minor
Status: ASSIGNED → NEW
Component: Layout → Layout: Block & Inline
QA Contact: petersen → ian
Blocks: 52109
Blocks: 23605
Isn't... <p><::before><::first-letter>"</::first-letter></::before><::first-letter>T</::first-letter>ext</p> ...more correct?
Keywords: qawanted
Summary: :first-letter and openquote :before should be together → ::first-letter and openquote ::before should be together
Assignee: core.layout.block-and-inline → mats.palmgren
Severity: minor → normal
Keywords: qawantedtestcase
Target Milestone: Future → ---
Attached file Testcase #1
Attached patch Patch rev. 1 (obsolete) — Splinter Review
I didn't know where to put the "IsPunctuationMark" functionallity... it's now copy-pasted in "nsCSSFrameConstructor.cpp" from "nsTextFrame.cpp". Maybe this should live in a string/i18n lib somewhere... please advice. This patch implements multi frame :first-letters to the level of CSS 2.0, i.e. it does not traverse child blocks. I have a patch for that too but the layout part isn't working yet so I would like to do that as a second stage.
Attached patch Patch rev. 1 (diff -uw) (obsolete) — Splinter Review
Blocks: 2418
Shared things can also go in nsLayoutUtils...
Attached patch Patch rev. 2 (obsolete) — Splinter Review
OK, I added the "IsPunctuationMark" stuff to nsLayoutUtils.
Attachment #166679 - Attachment is obsolete: true
Attachment #166680 - Attachment is obsolete: true
Attachment #169014 - Flags: superreview?(dbaron)
Attachment #169014 - Flags: review?(bzbarsky)
Attached patch Patch rev. 2 (diff -uw) (obsolete) — Splinter Review
I'm not likely to get to this review until after I get back to town... So not likely to happen before the alpha milestone ends.
Comment on attachment 169014 [details] [diff] [review] Patch rev. 2 >Index: layout/generic/nsIFrame.h >+// Text reflow bit >+#define TEXT_IN_WORD 0x04000000 >+ >+// First-letter layout bits >+#define NS_FIRST_LETTER_FIRST_FRAME 0x20000000 >+#define NS_FIRST_LETTER_LAST_FRAME 0x40000000 Document that these only have to be here because the relevant concrete classes don't have header files that you could put them in? Also document which exact concrete classes would use those bits. And while you're here, document what the bits mean? >Index: layout/generic/nsBlockFrame.cpp >+ if (nsLayoutAtoms::letterFrame == floatFrame->GetType()) { >+ nsFrameState frameState = floatFrame->GetStateBits(); >+ if (!(frameState & NS_FIRST_LETTER_FIRST_FRAME)) { >+ aFloatCache->mMargins.left = 0; >+ } >+ if (!(frameState & NS_FIRST_LETTER_LAST_FRAME)) { >+ aFloatCache->mMargins.right = 0; >+ } >+ } This could use a comment explaining why this is being done (though perhaps documenting those flags will be sufficient?) >Index: layout/generic/nsFirstLetterFrame.cpp >+nsFirstLetterFrame::PaintSelf(nsPresContext* >+ if (!(frameState & NS_FIRST_LETTER_FIRST_FRAME)) { >+ aSkipSides |= (1 << NS_SIDE_LEFT); >+ } >+ if (!(frameState & NS_FIRST_LETTER_LAST_FRAME)) { >+ aSkipSides |= (1 << NS_SIDE_RIGHT); >+ } Shouldn't this be handled by GetSkipSides()? Speaking of which, don't you need to fix GetSkipSides()? A lot of the places you set things to 0 may Just Work if you do that... I got up to the beginning of the nsLineLayout changes. More later.
Comment on attachment 169014 [details] [diff] [review] Patch rev. 2 >Index: layout/generic/nsIFrame.h >+// Text reflow bit >+#define TEXT_IN_WORD 0x04000000 >+ >+// First-letter layout bits >+#define NS_FIRST_LETTER_FIRST_FRAME 0x20000000 >+#define NS_FIRST_LETTER_LAST_FRAME 0x40000000 Please document which frame types those bits apply to, since they're in the "reserved for implementations" range. Also, it may be worth putting those in the relevant header files (and creating said header files if needed). I'm ok with that happening in a separate bug, but I really don't think that nsIFrame.h is the right place for implementation-specific flags. Also, please document what those bits mean. They're not very self-explanatory.... Knowing what they mean would make all the code that uses them _much_ clearer. >Index: layout/generic/nsBlockFrame.cpp >+ if (nsLayoutAtoms::letterFrame == floatFrame->GetType()) { Please document why floating letterframes that aren't the "first" or "last" (whatever that means) should have zero margins on the relevant side? >Index: layout/generic/nsBlockReflowState.cpp >+ nsIFrame* floatFrame = aPlaceholder->GetOutOfFlowFrame(); >+ if (floatFrame && nsLayoutAtoms::letterFrame == floatFrame->GetType()) { >+ fc->mIsCurrentLineFloat = PR_TRUE; Please document why this is being done. >@@ -816,25 +821,32 @@ nsBlockReflowState::FlowAndPlaceFloat(ns >+ if (nsLayoutAtoms::letterFrame == floatFrame->GetType()) { >+ // Keep all ::first-letter frames on the same line. >+ if (!(floatFrame->GetStateBits() & NS_FIRST_LETTER_FIRST_FRAME)) { >+ keepFloatOnSameLine = PR_TRUE; I think the comment should be something like: If there are multiple ::first-letter frames, make sure to put all of them on a line together. So if this isn't the first one, don't allow it to advance to the next band. >Index: layout/generic/nsFirstLetterFrame.cpp >+nsFirstLetterFrame::PaintSelf(nsPresContext* >+ nsFrame::PaintSelf(aPresContext, Why not nsFirstLetterFrameSuper::PaintSelf? If there is a good reason, document it here. Also, is there a reason you don't need to fix GetSkipSides? If you did fix it, would you still need to override PaintSelf? Did you test this with other things that use GetSkipSides (eg text-decoration in standards mode)? >Index: layout/generic/nsLineLayout.cpp >+ PRBool notSafeToBreak = CanPlaceFloatNow() || >+ InWord() || >+ (aFrame->GetStateBits() & TEXT_IN_WORD); Are you sure aFrame is a textframe? If not, this will do the wrong thing, no? I bet you need a frametype check here. >Index: layout/generic/nsTextFrame.cpp >+ // Trailing whitespace after ::first-letter punctuation >+ if (aTextData.mFirstLetterOK) { Could you document what exactly is being done here and why? In particular, documenting nsLineLayout a tad (to say what the "FirstLetterStyleOK" flag means) would go a long way toward understanding this code. Some explanation of why we're setting contentLen and wordLen and what the mState change means would also help (perhaps document that bit a little more extensively than is done now, say with an example?). >+ aTextData.mX = 1; Hmm.... This won't cause an unnecessary horizontal offset? Sorry, I just don't know this code very well. :( You may want to run this part of the patch by rbs, perhaps.... >Index: layout/base/nsLayoutUtils.h >+ * for ::first-letter's, see Remove the apostrophe (and perhaps the 's' too). >Index: layout/base/nsLayoutUtils.cpp >+// The following comemnt came from nsTextFrame.cpp, see the "comment" >Index: layout/base/nsCSSFrameConstructor.cpp >+ mPrefix(NS_FIRST_LETTER_PREFIX_EMPTY_OR_WS) {;} Why the ';' in there? Take it out, I think. >+ * aIsFirstLetter is true if this text fragment belongs to the :first-letter There is no such arg to this method.... >+ NS_ASSERTION(len == 0, "aText was not empty"); I think this would make more sense as an NS_PRECONDITION, with an unconditional "else" at the end here and an assert that |s| is true. This is as far as I got for now.... The letter frame construction and removal logic is pretty hairy, and I'll need to be much more awake to review it. :( Also, I'd sort of appreciate not making all the whitespace changes for the nsPresContext args, since I plan to remove those args altogether in the not-too-distant future....
rbs is not in Cc. perhaps, he's been watching it anyway. just to make sure..
Comment on attachment 169014 [details] [diff] [review] Patch rev. 2 Mats, would you mind updating the patch with the documentation I asked for in the first part of the review? That would make the rest of this review a _lot_ easier... As it stands, I just spent an hour and a bit looking at the patch and the code, and I still can't really sort out what's going on in a lot of it. Marking r- for now, but again, that's not really an indication that there is anything specific wrong, just that I can't tell.
Attachment #169014 - Flags: superreview?(dbaron)
Attachment #169014 - Flags: superreview-
Attachment #169014 - Flags: review?(bzbarsky)
Attachment #169014 - Flags: review-
I have missed the fact that trailing punctuation should also be included: http://www.w3.org/TR/CSS21/selector.html#first-letter "Punctuation ..., that precedes or follows the first letter should be included," I have code that fixes that, just need to clean it up a bit. The spec isn't clear on what to do when there is only punctuation, e.g. <p>"</p>. So far I have assumed that it should be included even when there is no first letter (this is the current behaviour), but when I now read the spec again I get the impression that this might not be what the spec author intended.
Attachment #169014 - Attachment is obsolete: true
Attachment #169015 - Attachment is obsolete: true
No longer blocks: 52109
*** Bug 52109 has been marked as a duplicate of this bug. ***
QA Contact: ian → layout.block-and-inline

Mass-removing myself from cc; search for 12b9dfe4-ece3-40dc-8d23-60e179f64ac1 or any reasonable part thereof, to mass-delete these notifications (and sorry!)

The bug assignee is inactive on Bugzilla, so the assignee is being reset.

Assignee: MatsPalmgren_bugz → nobody
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: