Changeset 75738 in webkit


Ignore:
Timestamp:
Jan 13, 2011 2:49:44 PM (13 years ago)
Author:
commit-queue@webkit.org
Message:

2011-01-13 Emil Eklund <eae@chromium.org>

Reviewed by Dimitri Glazkov.

Setting outerText should convert CR/LF to <br>
https://bugs.webkit.org/show_bug.cgi?id=52268

Add test for setting Element.outerText.

  • fast/dom/set-outer-text-expected.txt: Added.
  • fast/dom/set-outer-text.html: Added.
  • fast/dom/text-node-append-data-remove-crash-expected.txt: Changed

expectation to "didn't crash" from "threw dom exception" as test
assumed the DOMCharacterDataModified event would fire before the node
would be replaced.

  • fast/dom/text-node-append-data-remove-crash.html:

2011-01-13 Emil Eklund <eae@chromium.org>

Reviewed by Dimitri Glazkov.

Setting outerText should convert CR/LF to <br>
https://bugs.webkit.org/show_bug.cgi?id=52268

Make set outerText support line breaks (sharing the text to fragment code
with setInnerText) and handle empty text nodes the same way IE does.

Test: fast/dom/set-outer-text.html

  • html/HTMLElement.cpp: (WebCore::HTMLElement::textToFragment): Shared between setInnerText and setOuterText (WebCore::HTMLElement::setInnerText): Split out text parsing code. (WebCore::mergeWithNextTextNode): Split out text node merging code. (WebCore::HTMLElement::setOuterText): Added support for line breaks.
  • html/HTMLElement.h:
Location:
trunk
Files:
2 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r75737 r75738  
     12011-01-13  Emil Eklund  <eae@chromium.org>
     2
     3        Reviewed by Dimitri Glazkov.
     4
     5        Setting outerText should convert CR/LF to <br>
     6        https://bugs.webkit.org/show_bug.cgi?id=52268
     7       
     8        Add test for setting Element.outerText.
     9
     10        * fast/dom/set-outer-text-expected.txt: Added.
     11        * fast/dom/set-outer-text.html: Added.
     12        * fast/dom/text-node-append-data-remove-crash-expected.txt: Changed
     13            expectation to "didn't crash" from "threw dom exception" as test
     14            assumed the DOMCharacterDataModified event would fire before the node
     15            would be replaced.
     16        * fast/dom/text-node-append-data-remove-crash.html:
     17
    1182011-01-13  Adam Roben  <aroben@apple.com>
    219
  • trunk/LayoutTests/fast/dom/text-node-append-data-remove-crash-expected.txt

    r75519 r75738  
    1 PASS, threw an exception as expected - Error: HIERARCHY_REQUEST_ERR: DOM Exception 3
     1PASS, didn't crash.
  • trunk/LayoutTests/fast/dom/text-node-append-data-remove-crash.html

    r75519 r75738  
    1414       divBlock.addEventListener("DOMCharacterDataModified", eventListener, false);
    1515       pBlock.outerText = "text";
     16       divBlock.innerHTML = "PASS, didn't crash.";
    1617    }
    1718    catch (exception) {
    18        divBlock.innerHTML = "PASS, threw an exception as expected - " + exception;
    19        if (window.layoutTestController)
    20            layoutTestController.notifyDone();
    21    }
     19       divBlock.innerHTML = "Threw an exception - " + exception;
     20    }
     21    if (window.layoutTestController)
     22        layoutTestController.notifyDone();
    2223}
    2324
    2425function eventListener()
    2526{
    26     count += 1;
    27     if (count < 2)
    28         return;
    29     var range = document.createRange();
    30     range.setStart(divBlock, 0);
    31     range.setEnd(divBlock, divBlock.childNodes.length - 1);
    32     range.deleteContents();
    33     gc();
     27    try {
     28      var range = document.createRange();
     29      range.setStart(divBlock, 0);
     30      range.setEnd(divBlock, divBlock.childNodes.length - 1);
     31      range.deleteContents();
     32      gc();
     33  } catch(e) { }
    3434}
    3535
  • trunk/Source/WebCore/ChangeLog

    r75735 r75738  
     12011-01-13  Emil Eklund  <eae@chromium.org>
     2
     3        Reviewed by Dimitri Glazkov.
     4
     5        Setting outerText should convert CR/LF to <br>
     6        https://bugs.webkit.org/show_bug.cgi?id=52268
     7
     8        Make set outerText support line breaks (sharing the text to fragment code
     9        with setInnerText) and handle empty text nodes the same way IE does.
     10
     11        Test: fast/dom/set-outer-text.html
     12
     13        * html/HTMLElement.cpp:
     14        (WebCore::HTMLElement::textToFragment): Shared between setInnerText and setOuterText
     15        (WebCore::HTMLElement::setInnerText): Split out text parsing code.
     16        (WebCore::mergeWithNextTextNode): Split out text node merging code.
     17        (WebCore::HTMLElement::setOuterText): Added support for line breaks.
     18        * html/HTMLElement.h:
     19
    1202011-01-13  Zhenyao Mo  <zmo@google.com>
    221
  • trunk/Source/WebCore/html/HTMLElement.cpp

    r75519 r75738  
    377377}
    378378
     379PassRefPtr<DocumentFragment> HTMLElement::textToFragment(const String& text, ExceptionCode& ec)
     380{
     381    RefPtr<DocumentFragment> fragment = DocumentFragment::create(document());
     382    unsigned int i, length = text.length();
     383    UChar c = 0;
     384    for (unsigned int start = 0; start < length; ) {
     385
     386        // Find next line break.
     387        for (i = start; i < length; i++) {
     388          c = text[i];
     389          if (c == '\r' || c == '\n')
     390              break;
     391        }
     392
     393        fragment->appendChild(Text::create(document(), text.substring(start, i - start)), ec);
     394        if (ec)
     395            return 0;
     396
     397        if (c == '\r' || c == '\n') {
     398            fragment->appendChild(HTMLBRElement::create(document()), ec);
     399            if (ec)
     400                return 0;
     401            // Make sure \r\n doesn't result in two line breaks.
     402            if (c == '\r' && i + 1 < length && text[i + 1] == '\n')
     403                i++;
     404        }
     405
     406        start = i + 1; // Character after line break.
     407    }
     408
     409    return fragment;
     410}
     411
    379412void HTMLElement::setInnerText(const String& text, ExceptionCode& ec)
    380413{
     
    420453    // Add text nodes and <br> elements.
    421454    ec = 0;
    422     RefPtr<DocumentFragment> fragment = DocumentFragment::create(document());
    423     int lineStart = 0;
    424     UChar prev = 0;
    425     int length = text.length();
    426     for (int i = 0; i < length; ++i) {
    427         UChar c = text[i];
    428         if (c == '\n' || c == '\r') {
    429             if (i > lineStart) {
    430                 fragment->appendChild(Text::create(document(), text.substring(lineStart, i - lineStart)), ec);
    431                 if (ec)
    432                     return;
    433             }
    434             if (!(c == '\n' && i != 0 && prev == '\r')) {
    435                 fragment->appendChild(HTMLBRElement::create(document()), ec);
    436                 if (ec)
    437                     return;
    438             }
    439             lineStart = i + 1;
    440         }
    441         prev = c;
    442     }
    443     if (length > lineStart)
    444         fragment->appendChild(Text::create(document(), text.substring(lineStart, length - lineStart)), ec);
    445     replaceChildrenWithFragment(this, fragment.release(), ec);
     455    RefPtr<DocumentFragment> fragment = textToFragment(text, ec);
     456    if (!ec)
     457        replaceChildrenWithFragment(this, fragment.release(), ec);
     458}
     459
     460static void mergeWithNextTextNode(PassRefPtr<Node> node, ExceptionCode& ec)
     461{
     462    ASSERT(node && node->isTextNode());
     463    Node* next = node->nextSibling();
     464    if (!next || !next->isTextNode())
     465        return;
     466   
     467    RefPtr<Text> textNode = static_cast<Text*>(node.get());
     468    RefPtr<Text> textNext = static_cast<Text*>(next);
     469    textNode->appendData(textNext->data(), ec);
     470    if (ec)
     471        return;
     472    if (textNext->parentNode()) // Might have been removed by mutation event.
     473        textNext->remove(ec);
    446474}
    447475
     
    466494    }
    467495
    468     // FIXME: This creates a new text node even when the text is empty.
    469     // FIXME: This creates a single text node even when the text has CR and LF
    470     // characters in it. Instead it should create <br> elements.
    471     RefPtr<Text> t = Text::create(document(), text);
     496    RefPtr<Node> prev = previousSibling();
     497    RefPtr<Node> next = nextSibling();
     498    RefPtr<Node> newChild;
    472499    ec = 0;
    473     parent->replaceChild(t, this, ec);
     500   
     501    // Convert text to fragment with <br> tags instead of linebreaks if needed.
     502    if (text.contains('\r') || text.contains('\n'))
     503        newChild = textToFragment(text, ec);
     504    else
     505        newChild = Text::create(document(), text);
     506
     507    if (!this || !parentNode())
     508        ec = HIERARCHY_REQUEST_ERR;
    474509    if (ec)
    475510        return;
    476 
    477     // Is previous node a text node? If so, merge into it.
    478     Node* prev = t->previousSibling();
    479     if (prev && prev->isTextNode()) {
    480         RefPtr<Text> textPrev = static_cast<Text*>(prev);
    481         textPrev->appendData(t->data(), ec);
    482         if (ec)
    483             return;
    484         t->remove(ec);
    485         if (ec)
    486             return;
    487         t = textPrev;
    488     }
    489 
    490     // Is next node a text node? If so, merge it in.
    491     Node* next = t->nextSibling();
    492     if (next && next->isTextNode()) {
    493         RefPtr<Text> textNext = static_cast<Text*>(next);
    494         t->appendData(textNext->data(), ec);
    495         if (ec)
    496             return;
    497         textNext->remove(ec);
    498         if (ec)
    499             return;
    500     }
     511    parent->replaceChild(newChild.release(), this, ec);
     512
     513    RefPtr<Node> node = next ? next->previousSibling() : 0;
     514    if (!ec && node && node->isTextNode())
     515        mergeWithNextTextNode(node.release(), ec);
     516
     517    if (!ec && prev && prev->isTextNode())
     518        mergeWithNextTextNode(prev.release(), ec);
    501519}
    502520
  • trunk/Source/WebCore/html/HTMLElement.h

    r73430 r75738  
    101101
    102102    Node* insertAdjacent(const String& where, Node* newChild, ExceptionCode&);
     103    PassRefPtr<DocumentFragment> textToFragment(const String&, ExceptionCode&);
    103104};
    104105
Note: See TracChangeset for help on using the changeset viewer.