Changeset 13868 in webkit


Ignore:
Timestamp:
Apr 14, 2006 1:15:00 AM (18 years ago)
Author:
hyatt
Message:

Fix for 8333, make sure newlines in whitespace:pre (and friends) get
line boxes created for them. This resolves all the weird selection/navigation
issues that arise by not creating lines (and thus not having navigable positions
on those lines).

This checkin is also removing all of the layout test hacks that have piled
up, so layout test results are being regenerated completely.

Reviewed by eric

  • dom/Position.cpp: (WebCore::Position::downstream):
  • editing/CompositeEditCommand.cpp: (WebCore::CompositeEditCommand::moveParagraph):
  • editing/DeleteSelectionCommand.cpp: (WebCore::DeleteSelectionCommand::doApply):
  • editing/visible_units.cpp: (WebCore::startOfParagraph): (WebCore::endOfParagraph):
  • kwq/RenderTreeAsText.cpp: (getTagName): (operator<<):
  • rendering/InlineTextBox.cpp: (WebCore::InlineTextBox::selectionState): (WebCore::InlineTextBox::isLineBreak): (WebCore::InlineTextBox::nodeAtPoint): (WebCore::InlineTextBox::paint): (WebCore::InlineTextBox::offsetForPosition): (WebCore::InlineTextBox::positionForOffset):
  • rendering/InlineTextBox.h:
  • rendering/RenderBR.cpp:
  • rendering/RenderBR.h:
  • rendering/RenderText.cpp: (WebCore::RenderText::atLineWrap): (WebCore::RenderText::caretRect): (WebCore::RenderText::height): (WebCore::RenderText::inlineBox):
  • rendering/bidi.cpp: (WebCore::RenderBlock::computeHorizontalPositionsForLine): (WebCore::RenderBlock::layoutInlineChildren): (WebCore::RenderBlock::findNextLineBreak):
  • rendering/render_line.h: (WebCore::InlineBox::isLineBreak):
Location:
trunk/WebCore
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r13867 r13868  
     12006-04-14  David Hyatt  <hyatt@apple.com>
     2
     3        Fix for 8333, make sure newlines in whitespace:pre (and friends) get
     4        line boxes created for them.  This resolves all the weird selection/navigation
     5        issues that arise by not creating lines (and thus not having navigable positions
     6        on those lines).
     7
     8        This checkin is also removing all of the layout test hacks that have piled
     9        up, so layout test results are being regenerated completely.
     10
     11        Reviewed by eric
     12
     13        * dom/Position.cpp:
     14        (WebCore::Position::downstream):
     15        * editing/CompositeEditCommand.cpp:
     16        (WebCore::CompositeEditCommand::moveParagraph):
     17        * editing/DeleteSelectionCommand.cpp:
     18        (WebCore::DeleteSelectionCommand::doApply):
     19        * editing/visible_units.cpp:
     20        (WebCore::startOfParagraph):
     21        (WebCore::endOfParagraph):
     22        * kwq/RenderTreeAsText.cpp:
     23        (getTagName):
     24        (operator<<):
     25        * rendering/InlineTextBox.cpp:
     26        (WebCore::InlineTextBox::selectionState):
     27        (WebCore::InlineTextBox::isLineBreak):
     28        (WebCore::InlineTextBox::nodeAtPoint):
     29        (WebCore::InlineTextBox::paint):
     30        (WebCore::InlineTextBox::offsetForPosition):
     31        (WebCore::InlineTextBox::positionForOffset):
     32        * rendering/InlineTextBox.h:
     33        * rendering/RenderBR.cpp:
     34        * rendering/RenderBR.h:
     35        * rendering/RenderText.cpp:
     36        (WebCore::RenderText::atLineWrap):
     37        (WebCore::RenderText::caretRect):
     38        (WebCore::RenderText::height):
     39        (WebCore::RenderText::inlineBox):
     40        * rendering/bidi.cpp:
     41        (WebCore::RenderBlock::computeHorizontalPositionsForLine):
     42        (WebCore::RenderBlock::layoutInlineChildren):
     43        (WebCore::RenderBlock::findNextLineBreak):
     44        * rendering/render_line.h:
     45        (WebCore::InlineBox::isLineBreak):
     46
    1472006-04-13  Darin Adler  <darin@apple.com>
    248
  • trunk/WebCore/dom/Position.cpp

    r13865 r13868  
    433433               
    434434                if (box != textRenderer->lastTextBox() &&
    435                      !box->nextOnLine() && 
     435                     !box->nextOnLine() &&
    436436                     textOffset == box->start() + box->len()) {
    437437                    return currentPos;
  • trunk/WebCore/editing/CompositeEditCommand.cpp

    r13859 r13868  
    690690   
    691691    // Deleting a paragraph leaves a placeholder (it always does when a whole paragraph is deleted).
    692     // We remove it and prune it's parents since we want to remove all traces of the paragraph we're moving.
     692    // We remove it and prune its parents since we want to remove all traces of the paragraph we're moving.
    693693    Node* placeholder = endingSelection().end().node();
    694694    if (placeholder->hasTagName(brTag))
  • trunk/WebCore/editing/DeleteSelectionCommand.cpp

    r13854 r13868  
    601601        return;
    602602
    603     // If the deletion is occuring in a text field, let the frame call across the bridge to notify the form delegate.
     603    // If the deletion is occurring in a text field, let the frame call across the bridge to notify the form delegate.
    604604    Node* startNode = m_selectionToDelete.start().node();
    605605    Node* ancestorNode = startNode ? startNode->shadowAncestorNode() : 0;
     
    627627                               isEndOfParagraph(VisiblePosition(m_downstreamEnd));
    628628
    629     // Delete any text that may hinder our ability to fixup whitespace after the detele
     629    // Delete any text that may hinder our ability to fixup whitespace after the delete
    630630    deleteInsignificantTextDownstream(m_trailingWhitespace);   
    631631
  • trunk/WebCore/editing/visible_units.cpp

    r13859 r13868  
    563563            break;
    564564        if (r->isText()) {
    565             // FIXME: Not clear what to do with pre-wrap or pre-line here.
    566             if (style->whiteSpace() == PRE) {
     565            if (style->preserveNewline()) {
    567566                const QChar* text = static_cast<RenderText*>(r)->text();
    568567                int i = static_cast<RenderText*>(r)->length();
     
    624623        if (r->isText() && r->caretMaxRenderedOffset() > 0) {
    625624            int length = static_cast<RenderText *>(r)->length();
    626             // FIXME: Not clear what to do with pre-wrap or pre-line here.
    627             if (style->whiteSpace() == PRE) {
     625            if (style->preserveNewline()) {
    628626                const QChar* text = static_cast<RenderText *>(r)->text();
    629627                int o = n == startNode ? offset : 0;
  • trunk/WebCore/rendering/InlineTextBox.cpp

    r13859 r13868  
    8080{
    8181    RenderObject::SelectionState state = object()->selectionState();
    82     if (state == RenderObject::SelectionStart || state == RenderObject::SelectionEnd ||
    83         state == RenderObject::SelectionBoth) {
     82    if (state == RenderObject::SelectionStart || state == RenderObject::SelectionEnd || state == RenderObject::SelectionBoth) {
    8483        int startPos, endPos;
    8584        object()->selectionStartEnd(startPos, endPos);
    8685       
     86        // If we're at a line wrap, then the selection is going to extend onto the next line (and thus needs to be thought of as
     87        // extending beyond our box.
     88        if (textObject()->atLineWrap(this, endPos))
     89            endPos++;
     90
    8791        bool start = (state != RenderObject::SelectionEnd && startPos >= m_start && startPos < m_start + m_len);
    8892        bool end = (state != RenderObject::SelectionStart && endPos > m_start && endPos <= m_start + m_len);
     
    219223}
    220224
     225bool InlineTextBox::isLineBreak() const
     226{
     227    return object()->isBR() || (object()->style()->preserveNewline() && len() == 1 && (*textObject()->string())[start()] == '\n');
     228}
     229
    221230bool InlineTextBox::nodeAtPoint(RenderObject::NodeInfo& i, int x, int y, int tx, int ty)
    222231{
    223     if (object()->isBR())
     232    if (isLineBreak())
    224233        return false;
    225234
     
    234243void InlineTextBox::paint(RenderObject::PaintInfo& i, int tx, int ty)
    235244{
    236     if (object()->isBR() || !object()->shouldPaintWithinRoot(i) || object()->style()->visibility() != VISIBLE ||
     245    if (isLineBreak() || !object()->shouldPaintWithinRoot(i) || object()->style()->visibility() != VISIBLE ||
    237246        m_truncation == cFullTruncation || i.phase == PaintPhaseOutline)
    238247        return;
     
    684693int InlineTextBox::offsetForPosition(int _x, bool includePartialGlyphs) const
    685694{
     695    if (isLineBreak())
     696        return 0;
     697
    686698    RenderText* text = static_cast<RenderText*>(m_object);
    687699    RenderStyle *style = text->style(m_firstLine);
     
    694706int InlineTextBox::positionForOffset(int offset) const
    695707{
     708    if (isLineBreak())
     709        return m_x;
     710
    696711    RenderText *text = static_cast<RenderText *>(m_object);
    697712    const Font *f = text->font(m_firstLine);
  • trunk/WebCore/rendering/InlineTextBox.h

    r13595 r13868  
    8686    virtual int placeEllipsisBox(bool ltr, int blockEdge, int ellipsisWidth, bool& foundBox);
    8787
     88    virtual bool isLineBreak() const;
     89
    8890    // Overloaded new operator.  Derived classes must override operator new
    8991    // in order to allocate out of the RenderArena.
  • trunk/WebCore/rendering/RenderBR.cpp

    r13393 r13868  
    108108}
    109109
    110 IntRect RenderBR::caretRect(int offset, EAffinity affinity, int *extraWidthToEndOfLine)
    111 {
    112     // EDIT FIXME: This does not work yet. Some other changes are need before
    113     // an accurate position can be determined.
    114 
    115     int absx, absy;
    116     absolutePosition(absx, absy);
    117 
    118     if (extraWidthToEndOfLine)
    119         *extraWidthToEndOfLine = containingBlockWidth() - xPos();
    120  
    121     // FIXME: an older version of this code wasn't setting width at
    122     // all, using the default of 1...
    123     return IntRect(xPos() + absx, yPos() + absy, 1, lineHeight(false));
    124 }
    125 
    126110InlineBox *RenderBR::inlineBox(int offset, EAffinity affinity)
    127111{
  • trunk/WebCore/rendering/RenderBR.h

    r13393 r13868  
    5454    // overrides
    5555    virtual InlineBox* createInlineBox(bool, bool, bool isOnlyRun = false);
    56     virtual void calcMinMaxWidth() {}
    57     virtual int minWidth() const { return 0; }
    58     virtual int maxWidth() const { return 0; }
    5956
    6057    virtual bool isBR() const { return true; }
     
    6562   
    6663    virtual VisiblePosition positionForCoordinates(int x, int y);
    67     virtual IntRect caretRect(int offset, EAffinity affinity = UPSTREAM, int *extraWidthToEndOfLine = 0);
    6864
    6965    virtual InlineBox *inlineBox(int offset, EAffinity affinity = UPSTREAM);
  • trunk/WebCore/rendering/RenderText.cpp

    r13859 r13868  
    352352{
    353353    if (box->nextTextBox() && !box->nextOnLine() && offset == box->m_start + box->m_len) {
    354         // Take special care because in preformatted text, the newlines
    355         // are in between the text boxes (i.e. not in any box's m_start
    356         // thru m_start+m_len-1), even though they are rendered.
    357         if (!style()->preserveNewline() || (*str)[offset] != '\n')
     354        if (!style()->preserveNewline() || box->isLineBreak())
    358355            return true;
    359356    }
     
    372369        if ((offset >= box->m_start) && (offset <= box->m_start + box->m_len)) {
    373370            // Check if downstream affinity would make us move to the next line.
    374             if (affinity == DOWNSTREAM && atLineWrap(box, offset)) {
     371            if (atLineWrap(box, offset)) {
    375372                // Use the next text box
    376373                box = box->nextTextBox();
     
    920917int RenderText::height() const
    921918{
    922     // FIXME: Why use line-height? Shouldn't we be adding in the height of the last text box? -dwh
    923919    int retval = 0;
    924920    if (firstTextBox())
    925         retval = lastTextBox()->m_y + lineHeight(false) - firstTextBox()->m_y;
     921        retval = lastTextBox()->m_y + lastTextBox()->height() - firstTextBox()->m_y;
    926922    return retval;
    927923}
     
    11121108    for (InlineTextBox *box = firstTextBox(); box; box = box->nextTextBox()) {
    11131109        if (offset >= box->m_start && offset <= box->m_start + box->m_len) {
    1114             if (affinity == DOWNSTREAM && atLineWrap(box, offset))
     1110            if (atLineWrap(box, offset))
    11151111                return box->nextTextBox();
    11161112            return box;
  • trunk/WebCore/rendering/RenderTreeAsText.cpp

    r13867 r13868  
    103103    if (n->isDocumentNode())
    104104        return "";
    105     if (n->isTextNode())
    106         return "TEXT"; // FIXME: Remove once the layout tests are ready to change.
    107105    if (n->isCommentNode())
    108106        return "COMMENT";
    109     if (n->isHTMLElement())
    110         return n->nodeName().upper().deprecatedString(); // FIXME: We want to dump the real DOM name, not an uppercase name.
    111107    return n->nodeName().deprecatedString();
    112108}
     
    127123    }
    128124   
    129     // FIXME: Will remove this <br> code once all layout tests pass.  Until then, we can't really change
    130     // all the results easily.
    131     // FIXME: Will also remove the table row and section hacks once all layout tests pass.
    132     bool usePositions = true;
    133     bool useWidth = true;
    134     bool useHeight = true;
    135     if (o.isBR()) {
    136         const RenderBR* br = static_cast<const RenderBR*>(&o);
    137         usePositions = (br->firstTextBox() && br->firstTextBox()->isText());
    138     } else if (o.isTableRow())
    139         usePositions = useWidth = useHeight = false;
    140     else if (o.isTableSection())
    141         useWidth = false;
    142 
    143     IntRect r(usePositions ? o.xPos() : 0, usePositions ? o.yPos() : 0, useWidth ? o.width() : 0, useHeight ? o.height() : 0);
     125    IntRect r(o.xPos(), o.yPos(), o.width(), o.height());
    144126    ts << " " << r;
    145127   
  • trunk/WebCore/rendering/bidi.cpp

    r13859 r13868  
    102102static bool isLineEmpty = true;
    103103static bool previousLineBrokeCleanly = true;
    104 static bool skipTrailingNewline = false;
    105104static bool emptyRun = true;
    106105static int numSpaces;
     
    855854    bool needsWordSpacing = false;
    856855    for (r = sFirstBidiRun; r; r = r->nextRun) {
    857         if (!r->box || r->obj->isPositioned())
     856        if (!r->box || r->obj->isPositioned() || r->box->isLineBreak())
    858857            continue; // Positioned objects are only participating to figure out their
    859858                      // correct static x position.  They have no effect on the width.
     859                      // Similarly, line break boxes have no effect on the width.
    860860        if (r->obj->isText()) {
    861861            RenderText *rt = static_cast<RenderText *>(r->obj);
     
    16311631                }
    16321632               
    1633                 if (end == start || skipTrailingNewline) {
     1633                if (end == start) {
    16341634                    bidi.adjustEmbedding = true;
    16351635                    end.increment(bidi);
     
    19751975    bool prevLineBrokeCleanly = previousLineBrokeCleanly;
    19761976    previousLineBrokeCleanly = false;
    1977     skipTrailingNewline = false;
    19781977   
    19791978    while (o) {
     
    21872186
    21882187                if (c == '\n' || (o->style()->whiteSpace() != PRE && isBreakable(str, pos, strlen, nextBreakable, breakNBSP)) || midWordBreak) {
     2188                    bool stoppedIgnoringSpaces = false;
    21892189                    if (ignoringSpaces) {
    21902190                        if (!currentCharacterIsSpace) {
     
    21962196                            BidiIterator startMid ( 0, o, pos );
    21972197                            addMidpoint(startMid);
     2198                            stoppedIgnoringSpaces = true;
    21982199                        } else {
    21992200                            // Just keep ignoring these spaces.
     
    22502251                            }
    22512252                            if (lBreak.obj && lBreak.obj->style()->preserveNewline() && lBreak.obj->isText() && static_cast<RenderText*>(lBreak.obj)->text()[lBreak.pos] == '\n') {
     2253                                if (!stoppedIgnoringSpaces && pos > 0) {
     2254                                    // We need to stop right before the newline and then start up again.
     2255                                    BidiIterator midpoint(0, o, pos);
     2256                                    addMidpoint(BidiIterator(0, o, pos-1)); // Stop
     2257                                    addMidpoint(BidiIterator(0, o, pos)); // Start
     2258                                }
     2259                                lBreak.increment(bidi);
    22522260                                previousLineBrokeCleanly = true;
    2253                                 skipTrailingNewline = true;
    22542261                            }
    22552262                            goto end; // Didn't fit. Jump to the end.
     
    22642271
    22652272                    if (c == '\n' && o->style()->preserveNewline()) {
     2273                        if (!stoppedIgnoringSpaces && pos > 0) {
     2274                            // We need to stop right before the newline and then start up again.
     2275                            BidiIterator midpoint(0, o, pos);
     2276                            addMidpoint(BidiIterator(0, o, pos-1)); // Stop
     2277                            addMidpoint(BidiIterator(0, o, pos)); // Start
     2278                        }
    22662279                        lBreak.obj = o;
    22672280                        lBreak.pos = pos;
     2281                        lBreak.increment(bidi);
    22682282                        previousLineBrokeCleanly = true;
    2269                         skipTrailingNewline = true;
    22702283                        return lBreak;
    22712284                    }
  • trunk/WebCore/rendering/render_line.h

    r13859 r13868  
    6060    virtual void attachLine();
    6161
     62    virtual bool isLineBreak() const { return false; }
     63
    6264    virtual void adjustPosition(int dx, int dy);
    6365
Note: See TracChangeset for help on using the changeset viewer.