Commit b43c5185 authored by harrison's avatar harrison

Reviewed by Dave Hyatt (rendering) and Maciej (editing).

        Test cases added:  Coming soon.  Will include with next round of changes for this bug.

        This is the first checkin for...

        <rdar://problem/3792529> REGRESSION (Mail): Tabs do not work the way they did in Panther (especially useful in plain text mail)

        Basic strategy is to put tabs into spans with white-space:pre style, and
        render them with tabs stops every 8th space, where the space width and
        the left margin are those of the enclosing block.

        What's left is to switch to implement white-space:pre-wrap so
        that we can coalesce consecutive tabs while maintaining proper
        line breaking.  That will keep the markup smaller.

        * khtml/editing/apply_style_command.cpp:
        (khtml::createStyleSpanElement):
        (khtml::ApplyStyleCommand::removeCSSStyle):
        (khtml::ApplyStyleCommand::addInlineStyleIfNeeded):
        * khtml/editing/delete_selection_command.cpp:
        (khtml::DeleteSelectionCommand::saveTypingStyleState):
        * khtml/editing/edit_command.cpp:
        (khtml::EditCommand::styleAtPosition):
        * khtml/editing/html_interchange.h:
        * khtml/editing/htmlediting.cpp:
        (khtml::isSpecialElement):
        (khtml::isTabSpanNode):
        (khtml::isTabSpanTextNode):
        (khtml::positionBeforeTabSpan):
        (khtml::createTabSpanElement):
        * khtml/editing/htmlediting.h:
        * khtml/editing/insert_text_command.cpp:
        (khtml::InsertTextCommand::prepareForTextInsertion):
        (khtml::InsertTextCommand::input):
        (khtml::InsertTextCommand::insertTab):
        * khtml/editing/insert_text_command.h:
        * khtml/editing/markup.cpp:
        (khtml::createParagraphContentsFromString):
        (khtml::createFragmentFromText):
        * khtml/editing/replace_selection_command.cpp:
        (khtml::ReplacementFragment::removeStyleNodes):
        * khtml/html/htmltokenizer.cpp:
        (khtml::HTMLTokenizer::begin):
        (khtml::HTMLTokenizer::processListing):
        (khtml::HTMLTokenizer::parseEntity):
        (khtml::HTMLTokenizer::parseTag):
        (khtml::HTMLTokenizer::addPending):
        (khtml::HTMLTokenizer::write):
        * khtml/html/htmltokenizer.h:
        (khtml::HTMLTokenizer::):
        * khtml/rendering/bidi.cpp:
        (khtml::addRun):
        (khtml::RenderBlock::tabWidth):
        (khtml::RenderBlock::computeHorizontalPositionsForLine):
        (khtml::RenderBlock::skipWhitespace):
        (khtml::RenderBlock::findNextLineBreak):
        (khtml::RenderBlock::checkLinesForTextOverflow):
        * khtml/rendering/break_lines.cpp:
        (khtml::isBreakable):
        * khtml/rendering/font.cpp:
        (Font::drawHighlightForText):
        (Font::drawText):
        (Font::floatWidth):
        (Font::floatCharacterWidths):
        (Font::checkSelectionPoint):
        (Font::width):
        * khtml/rendering/font.h:
        * khtml/rendering/render_block.cpp:
        (khtml::stripTrailingSpace):
        (khtml::RenderBlock::calcInlineMinMaxWidth):
        * khtml/rendering/render_block.h:
        * khtml/rendering/render_br.h:
        (khtml::RenderBR::width):
        * khtml/rendering/render_flexbox.cpp:
        (khtml::RenderFlexibleBox::layoutVerticalBox):
        * khtml/rendering/render_image.cpp:
        (RenderImage::setPixmap):
        (RenderImage::paint):
        * khtml/rendering/render_line.cpp:
        (khtml::EllipsisBox::paint):
        * khtml/rendering/render_line.h:
        (khtml::InlineBox::width):
        (khtml::InlineBox::xPos):
        (khtml::InlineBox::yPos):
        (khtml::InlineBox::height):
        (khtml::InlineBox::baseline):
        * khtml/rendering/render_list.cpp:
        (RenderListMarker::paint):
        (RenderListMarker::calcMinMaxWidth):
        * khtml/rendering/render_object.cpp:
        (RenderObject::tabWidth):
        (RenderObject::recalcMinMaxWidths):
        * khtml/rendering/render_object.h:
        * khtml/rendering/render_replaced.cpp:
        * khtml/rendering/render_text.cpp:
        (InlineTextBox::selectionRect):
        (InlineTextBox::paint):
        (InlineTextBox::paintSelection):
        (InlineTextBox::paintMarkedTextBackground):
        (InlineTextBox::textPos):
        (InlineTextBox::offsetForPosition):
        (InlineTextBox::positionForOffset):
        (RenderText::cacheWidths):
        (RenderText::widthFromCache):
        (RenderText::trimmedMinMaxWidth):
        (RenderText::calcMinMaxWidth):
        (RenderText::containsOnlyWhitespace):
        (RenderText::width):
        * khtml/rendering/render_text.h:
        * kwq/KWQFontMetrics.h:
        * kwq/KWQFontMetrics.mm:
        (QFontMetrics::width):
        (QFontMetrics::charWidth):
        (QFontMetrics::floatWidth):
        (QFontMetrics::floatCharacterWidths):
        (QFontMetrics::checkSelectionPoint):
        (QFontMetrics::boundingRect):
        (QFontMetrics::size):
        * kwq/KWQPainter.h:
        * kwq/KWQPainter.mm:
        (QPainter::drawText):
        (QPainter::drawHighlightForText):
        * kwq/WebCoreTextRenderer.h:
        * kwq/WebCoreTextRendererFactory.mm:
        (WebCoreInitializeEmptyTextStyle):
        * layout-tests/editing/deleting/delete-tab-001-expected.txt:
        * layout-tests/editing/deleting/delete-tab-001.html:
        * layout-tests/editing/deleting/delete-tab-002-expected.txt:
        * layout-tests/editing/deleting/delete-tab-002.html:
        * layout-tests/editing/deleting/delete-tab-003-expected.txt:
        * layout-tests/editing/deleting/delete-tab-003.html:
        * layout-tests/editing/deleting/delete-tab-004-expected.txt:
        * layout-tests/editing/deleting/delete-tab-004.html:
        * layout-tests/editing/inserting/insert-tab-001-expected.txt:
        * layout-tests/editing/inserting/insert-tab-002-expected.txt:
        * layout-tests/editing/inserting/insert-tab-003-expected.txt:
        * layout-tests/editing/inserting/insert-tab-004-expected.txt:
        * layout-tests/fast/dom/quadraticCurveTo-expected.txt:
        * layout-tests/fast/js/string-replace-2-expected.txt:
        * layout-tests/fast/table/039-expected.txt:
        * layout-tests/fast/table/border-collapsing/004-expected.txt:
        * layout-tests/fast/tokenizer/script_extra_close-expected.txt:


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@9540 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent b0aae7df
......@@ -4,8 +4,11 @@ layer at (0,0) size 800x600
RenderBlock {HTML} at (0,0) size 800x600
RenderBody {BODY} at (8,8) size 784x584
RenderBlock {DIV} at (0,0) size 784x56 [border: (2px solid #FF0000)]
RenderInline {SPAN} at (0,0) size 56x28
RenderText {TEXT} at (14,14) size 56x28
text run at (14,14) width 56: " foo"
RenderInline {SPAN} at (0,0) size 80x28
RenderInline {SPAN} at (0,0) size 48x28
RenderText {TEXT} at (14,14) size 48x28
text run at (14,14) width 48: "\x{9}"
RenderText {TEXT} at (62,14) size 32x28
text run at (62,14) width 32: "foo"
RenderText {TEXT} at (0,0) size 0x0
caret: position 4 of child 0 {TEXT} of child 1 {SPAN} of child 1 {DIV} of child 1 {BODY} of child 0 {HTML} of document
caret: position 1 of child 0 {TEXT} of child 0 {SPAN} of child 1 {SPAN} of child 1 {DIV} of child 1 {BODY} of child 0 {HTML} of document
......@@ -15,8 +15,7 @@
function editingTest() {
typeCharacterCommand('\t');
typeCharacterCommand('\t');
for (i = 0; i < 4; i++)
deleteCommand();
deleteCommand();
}
</script>
......
......@@ -4,7 +4,10 @@ layer at (0,0) size 800x600
RenderBlock {HTML} at (0,0) size 800x600
RenderBody {BODY} at (8,8) size 784x584
RenderBlock {DIV} at (0,0) size 784x56 [border: (2px solid #FF0000)]
RenderInline {SPAN} at (0,0) size 56x28
RenderText {TEXT} at (14,14) size 56x28
text run at (14,14) width 56: "foo "
caret: position 7 of child 0 {TEXT} of child 1 {SPAN} of child 1 {DIV} of child 1 {BODY} of child 0 {HTML} of document
RenderInline {SPAN} at (0,0) size 48x28
RenderText {TEXT} at (14,14) size 32x28
text run at (14,14) width 32: "foo"
RenderInline {SPAN} at (0,0) size 16x28
RenderText {TEXT} at (46,14) size 16x28
text run at (46,14) width 16: "\x{9}"
caret: position 1 of child 0 {TEXT} of child 1 {SPAN} of child 1 {SPAN} of child 1 {DIV} of child 1 {BODY} of child 0 {HTML} of document
......@@ -17,8 +17,7 @@ function editingTest() {
moveSelectionForwardByCharacterCommand();
typeCharacterCommand('\t');
typeCharacterCommand('\t');
for (i = 0; i < 4; i++)
deleteCommand();
deleteCommand();
}
</script>
......
......@@ -4,8 +4,13 @@ layer at (0,0) size 800x600
RenderBlock {HTML} at (0,0) size 800x600
RenderBody {BODY} at (8,8) size 784x584
RenderBlock {DIV} at (0,0) size 784x56 [border: (2px solid #FF0000)]
RenderInline {SPAN} at (0,0) size 56x28
RenderText {TEXT} at (14,14) size 56x28
text run at (14,14) width 56: "fo o"
RenderInline {SPAN} at (0,0) size 60x28
RenderText {TEXT} at (14,14) size 20x28
text run at (14,14) width 20: "fo"
RenderInline {SPAN} at (0,0) size 28x28
RenderText {TEXT} at (34,14) size 28x28
text run at (34,14) width 28: "\x{9}"
RenderText {TEXT} at (62,14) size 12x28
text run at (62,14) width 12: "o"
RenderText {TEXT} at (0,0) size 0x0
caret: position 6 of child 0 {TEXT} of child 1 {SPAN} of child 1 {DIV} of child 1 {BODY} of child 0 {HTML} of document
caret: position 1 of child 0 {TEXT} of child 1 {SPAN} of child 1 {SPAN} of child 1 {DIV} of child 1 {BODY} of child 0 {HTML} of document
......@@ -17,8 +17,7 @@ function editingTest() {
moveSelectionForwardByCharacterCommand();
typeCharacterCommand('\t');
typeCharacterCommand('\t');
for (i = 0; i < 4; i++)
deleteCommand();
deleteCommand();
}
</script>
......
......@@ -4,9 +4,12 @@ layer at (0,0) size 800x600
RenderBlock {HTML} at (0,0) size 800x600
RenderBody {BODY} at (8,8) size 784x584
RenderBlock {DIV} at (0,0) size 784x84 [border: (2px solid #FF0000)]
RenderInline {SPAN} at (0,0) size 56x56
RenderInline {SPAN} at (0,0) size 80x56
RenderBR {BR} at (14,14) size 0x28
RenderText {TEXT} at (14,42) size 56x28
text run at (14,42) width 56: " foo"
RenderInline {SPAN} at (0,0) size 48x28
RenderText {TEXT} at (14,42) size 48x28
text run at (14,42) width 48: "\x{9}"
RenderText {TEXT} at (62,42) size 32x28
text run at (62,42) width 32: "foo"
RenderText {TEXT} at (0,0) size 0x0
caret: position 4 of child 1 {TEXT} of child 1 {SPAN} of child 1 {DIV} of child 1 {BODY} of child 0 {HTML} of document
caret: position 1 of child 0 {TEXT} of child 1 {SPAN} of child 1 {SPAN} of child 1 {DIV} of child 1 {BODY} of child 0 {HTML} of document
......@@ -16,8 +16,7 @@ function editingTest() {
insertLineBreakCommand();
typeCharacterCommand('\t');
typeCharacterCommand('\t');
for (i = 0; i < 4; i++)
deleteCommand();
deleteCommand();
}
</script>
......
......@@ -4,8 +4,11 @@ layer at (0,0) size 800x600
RenderBlock {HTML} at (0,0) size 800x600
RenderBody {BODY} at (8,8) size 784x584
RenderBlock {DIV} at (0,0) size 784x56 [border: (2px solid #FF0000)]
RenderInline {SPAN} at (0,0) size 56x28
RenderText {TEXT} at (14,14) size 56x28
text run at (14,14) width 56: " foo"
RenderInline {SPAN} at (0,0) size 80x28
RenderInline {SPAN} at (0,0) size 48x28
RenderText {TEXT} at (14,14) size 48x28
text run at (14,14) width 48: "\x{9}"
RenderText {TEXT} at (62,14) size 32x28
text run at (62,14) width 32: "foo"
RenderText {TEXT} at (0,0) size 0x0
caret: position 4 of child 0 {TEXT} of child 1 {SPAN} of child 1 {DIV} of child 1 {BODY} of child 0 {HTML} of document
caret: position 1 of child 0 {TEXT} of child 0 {SPAN} of child 1 {SPAN} of child 1 {DIV} of child 1 {BODY} of child 0 {HTML} of document
......@@ -4,8 +4,11 @@ layer at (0,0) size 800x600
RenderBlock {HTML} at (0,0) size 800x600
RenderBody {BODY} at (8,8) size 784x584
RenderBlock {DIV} at (0,0) size 784x56 [border: (2px solid #FF0000)]
RenderInline {SPAN} at (0,0) size 56x28
RenderText {TEXT} at (14,14) size 56x28
text run at (14,14) width 56: "foo "
RenderInline {SPAN} at (0,0) size 48x28
RenderText {TEXT} at (14,14) size 32x28
text run at (14,14) width 32: "foo"
RenderInline {SPAN} at (0,0) size 16x28
RenderText {TEXT} at (46,14) size 16x28
text run at (46,14) width 16: "\x{9}"
RenderText {TEXT} at (0,0) size 0x0
caret: position 7 of child 0 {TEXT} of child 1 {SPAN} of child 1 {DIV} of child 1 {BODY} of child 0 {HTML} of document
caret: position 1 of child 0 {TEXT} of child 1 {SPAN} of child 1 {SPAN} of child 1 {DIV} of child 1 {BODY} of child 0 {HTML} of document
......@@ -4,8 +4,13 @@ layer at (0,0) size 800x600
RenderBlock {HTML} at (0,0) size 800x600
RenderBody {BODY} at (8,8) size 784x584
RenderBlock {DIV} at (0,0) size 784x56 [border: (2px solid #FF0000)]
RenderInline {SPAN} at (0,0) size 56x28
RenderText {TEXT} at (14,14) size 56x28
text run at (14,14) width 56: "fo o"
RenderInline {SPAN} at (0,0) size 60x28
RenderText {TEXT} at (14,14) size 20x28
text run at (14,14) width 20: "fo"
RenderInline {SPAN} at (0,0) size 28x28
RenderText {TEXT} at (34,14) size 28x28
text run at (34,14) width 28: "\x{9}"
RenderText {TEXT} at (62,14) size 12x28
text run at (62,14) width 12: "o"
RenderText {TEXT} at (0,0) size 0x0
caret: position 6 of child 0 {TEXT} of child 1 {SPAN} of child 1 {DIV} of child 1 {BODY} of child 0 {HTML} of document
caret: position 1 of child 0 {TEXT} of child 1 {SPAN} of child 1 {SPAN} of child 1 {DIV} of child 1 {BODY} of child 0 {HTML} of document
......@@ -4,9 +4,12 @@ layer at (0,0) size 800x600
RenderBlock {HTML} at (0,0) size 800x600
RenderBody {BODY} at (8,8) size 784x584
RenderBlock {DIV} at (0,0) size 784x84 [border: (2px solid #FF0000)]
RenderInline {SPAN} at (0,0) size 56x56
RenderInline {SPAN} at (0,0) size 80x56
RenderBR {BR} at (14,14) size 0x28
RenderText {TEXT} at (14,42) size 56x28
text run at (14,42) width 56: " foo"
RenderInline {SPAN} at (0,0) size 48x28
RenderText {TEXT} at (14,42) size 48x28
text run at (14,42) width 48: "\x{9}"
RenderText {TEXT} at (62,42) size 32x28
text run at (62,42) width 32: "foo"
RenderText {TEXT} at (0,0) size 0x0
caret: position 4 of child 1 {TEXT} of child 1 {SPAN} of child 1 {DIV} of child 1 {BODY} of child 0 {HTML} of document
caret: position 1 of child 0 {TEXT} of child 1 {SPAN} of child 1 {SPAN} of child 1 {DIV} of child 1 {BODY} of child 0 {HTML} of document
......@@ -4,9 +4,8 @@ layer at (0,0) size 800x414
RenderBlock {HTML} at (0,0) size 800x414
RenderBody {BODY} at (8,16) size 784x18
RenderBlock {P} at (0,0) size 784x18
RenderText {TEXT} at (0,0) size 420x18
text run at (0,0) width 358: "\x{9}\x{9}\x{9}This test case should produce a sine-wave stroked with 1"
text run at (358,0) width 62: "px black. "
text run at (420,0) width 0: "\x{9}\x{9}"
RenderText {TEXT} at (0,0) size 416x18
text run at (0,0) width 358: "This test case should produce a sine-wave stroked with 1"
text run at (358,0) width 58: "px black."
RenderBlock (anonymous) at (0,50) size 800x364
RenderCanvasImage {CANVAS} at (0,0) size 480x360
......@@ -17,7 +17,7 @@ Your result: "-t's th- -nd -f th- w-rld -s w- kn-w -t, -nd - f--l f-n-."
Support for String.replace(/…/,myFunction)
function Capitalize(s){
return s.toUpperCase();
return s.toUpperCase();
}
result = foo.replace(vowels,Capitalize);
Expected result: "It's thE End Of thE wOrld As wE knOw It, And I fEEl fInE."
......@@ -26,7 +26,7 @@ Your result: "It's thE End Of thE wOrld As wE knOw It, And I fEEl fInE."
Support for String.replace(/…/,myFunction), using RegExp
function Capitalize(){
return RegExp.$1.toUpperCase()+RegExp.$2;
return RegExp.$1.toUpperCase()+RegExp.$2;
}
result = foo.replace(/([aeiou])([a-z])/g,Capitalize);
Expected result: "It's the End Of the wOrld As we knOw It, And I fEel fIne."
......@@ -35,7 +35,7 @@ Your result: "It's the End Of the wOrld As we knOw It, And I fEel fIne."
Support for String.replace(/…/,myFunction), using parameters
function Capitalize(orig,re1,re2){
return re1.toUpperCase()+re2;
return re1.toUpperCase()+re2;
}
result = foo.replace(/([aeiou])([a-z])/g,Capitalize);
Expected result: "It's the End Of the wOrld As we knOw It, And I fEel fIne."
......
......@@ -42,19 +42,11 @@ layer at (0,0) size 800x600
RenderText {TEXT} at (0,0) size 49x18
text run at (0,0) width 49: "Row 0:"
RenderText {TEXT} at (49,0) size 170x18
text run at (49,0) width 38: " (1,1) "
text run at (87,0) width 34: "(1,2) "
text run at (121,0) width 34: "(1,3) "
text run at (155,0) width 34: "(1,4) "
text run at (189,0) width 30: "(1,5)"
text run at (49,0) width 170: " (1,1)\x{9}(1,2)\x{9}(1,3)\x{9}(1,4)\x{9}(1,5)"
RenderBR {BR} at (0,0) size 0x0
RenderInline {B} at (0,0) size 49x18
RenderText {TEXT} at (0,18) size 49x18
text run at (0,18) width 49: "Row 1:"
RenderText {TEXT} at (49,18) size 170x18
text run at (49,18) width 38: " (2,1) "
text run at (87,18) width 34: "(2,2) "
text run at (121,18) width 34: "(2,3) "
text run at (155,18) width 34: "(2,4) "
text run at (189,18) width 30: "(2,5)"
text run at (49,18) width 170: " (2,1)\x{9}(2,2)\x{9}(2,3)\x{9}(2,4)\x{9}(2,5)"
RenderBR {BR} at (0,0) size 0x0
......@@ -17,9 +17,9 @@ layer at (0,0) size 800x1438
text run at (333,0) width 172: "The styles applied here are:"
RenderBlock {PRE} at (0,92) size 784x180
RenderText {TEXT} at (0,0) size 688x180
text run at (0,0) width 152: "TABLE { margin: 1"
text run at (0,0) width 152: "TABLE\x{9}{ margin: 1"
text run at (152,0) width 256: "em; border: medium solid blue; }"
text run at (0,15) width 368: "TD { border: thin solid green; padding: 5"
text run at (0,15) width 368: "TD\x{9}{ border: thin solid green; padding: 5"
text run at (368,15) width 40: "px; }"
text run at (0,30) width 352: "TH { border: medium solid purple; padding: 5"
text run at (352,30) width 40: "px; }"
......@@ -34,7 +34,7 @@ layer at (0,0) size 800x1438
text run at (0,120) width 328: "TABLE.five { border-collapse: separate; }"
text run at (0,135) width 464: "TABLE.five, TABLE.five TD, TABLE.five TH { border: none; }"
text run at (0,150) width 688: "TABLE.five TR, TABLE.five COL, TABLE.five COLGROUP, TABLE.five TBODY, TABLE.five THEAD"
text run at (0,165) width 296: " { border: medium solid red; }"
text run at (0,165) width 296: "\x{9}{ border: medium solid red; }"
RenderTable {TABLE} at (16,288) size 752x163
RenderTableSection {TBODY} at (0,0) size 0x163
RenderTableRow {TR} at (0,0) size 0x0
......
......@@ -4,7 +4,7 @@ layer at (0,0) size 800x600
RenderBlock {HTML} at (0,0) size 800x600
RenderBody {BODY} at (8,8) size 784x584
RenderText {TEXT} at (0,0) size 55x18
text run at (0,0) width 55: "TEST... "
text run at (0,0) width 55: "TEST...\x{9}"
RenderText {TEXT} at (0,0) size 0x0
RenderText {TEXT} at (0,0) size 0x0
RenderText {TEXT} at (55,0) size 232x18
......
2005-06-29 David Harrison <harrison@apple.com>
Reviewed by Dave Hyatt (rendering) and Maciej (editing).
Test cases added: Coming soon. Will include with next round of changes for this bug.
This is the first checkin for...
<rdar://problem/3792529> REGRESSION (Mail): Tabs do not work the way they did in Panther (especially useful in plain text mail)
Basic strategy is to put tabs into spans with white-space:pre style, and
render them with tabs stops every 8th space, where the space width and
the left margin are those of the enclosing block.
What's left is to switch to implement white-space:pre-wrap so
that we can coalesce consecutive tabs while maintaining proper
line breaking. That will keep the markup smaller.
* khtml/editing/apply_style_command.cpp:
(khtml::createStyleSpanElement):
(khtml::ApplyStyleCommand::removeCSSStyle):
(khtml::ApplyStyleCommand::addInlineStyleIfNeeded):
* khtml/editing/delete_selection_command.cpp:
(khtml::DeleteSelectionCommand::saveTypingStyleState):
* khtml/editing/edit_command.cpp:
(khtml::EditCommand::styleAtPosition):
* khtml/editing/html_interchange.h:
* khtml/editing/htmlediting.cpp:
(khtml::isSpecialElement):
(khtml::isTabSpanNode):
(khtml::isTabSpanTextNode):
(khtml::positionBeforeTabSpan):
(khtml::createTabSpanElement):
* khtml/editing/htmlediting.h:
* khtml/editing/insert_text_command.cpp:
(khtml::InsertTextCommand::prepareForTextInsertion):
(khtml::InsertTextCommand::input):
(khtml::InsertTextCommand::insertTab):
* khtml/editing/insert_text_command.h:
* khtml/editing/markup.cpp:
(khtml::createParagraphContentsFromString):
(khtml::createFragmentFromText):
* khtml/editing/replace_selection_command.cpp:
(khtml::ReplacementFragment::removeStyleNodes):
* khtml/html/htmltokenizer.cpp:
(khtml::HTMLTokenizer::begin):
(khtml::HTMLTokenizer::processListing):
(khtml::HTMLTokenizer::parseEntity):
(khtml::HTMLTokenizer::parseTag):
(khtml::HTMLTokenizer::addPending):
(khtml::HTMLTokenizer::write):
* khtml/html/htmltokenizer.h:
(khtml::HTMLTokenizer::):
* khtml/rendering/bidi.cpp:
(khtml::addRun):
(khtml::RenderBlock::tabWidth):
(khtml::RenderBlock::computeHorizontalPositionsForLine):
(khtml::RenderBlock::skipWhitespace):
(khtml::RenderBlock::findNextLineBreak):
(khtml::RenderBlock::checkLinesForTextOverflow):
* khtml/rendering/break_lines.cpp:
(khtml::isBreakable):
* khtml/rendering/font.cpp:
(Font::drawHighlightForText):
(Font::drawText):
(Font::floatWidth):
(Font::floatCharacterWidths):
(Font::checkSelectionPoint):
(Font::width):
* khtml/rendering/font.h:
* khtml/rendering/render_block.cpp:
(khtml::stripTrailingSpace):
(khtml::RenderBlock::calcInlineMinMaxWidth):
* khtml/rendering/render_block.h:
* khtml/rendering/render_br.h:
(khtml::RenderBR::width):
* khtml/rendering/render_flexbox.cpp:
(khtml::RenderFlexibleBox::layoutVerticalBox):
* khtml/rendering/render_image.cpp:
(RenderImage::setPixmap):
(RenderImage::paint):
* khtml/rendering/render_line.cpp:
(khtml::EllipsisBox::paint):
* khtml/rendering/render_line.h:
(khtml::InlineBox::width):
(khtml::InlineBox::xPos):
(khtml::InlineBox::yPos):
(khtml::InlineBox::height):
(khtml::InlineBox::baseline):
* khtml/rendering/render_list.cpp:
(RenderListMarker::paint):
(RenderListMarker::calcMinMaxWidth):
* khtml/rendering/render_object.cpp:
(RenderObject::tabWidth):
(RenderObject::recalcMinMaxWidths):
* khtml/rendering/render_object.h:
* khtml/rendering/render_replaced.cpp:
* khtml/rendering/render_text.cpp:
(InlineTextBox::selectionRect):
(InlineTextBox::paint):
(InlineTextBox::paintSelection):
(InlineTextBox::paintMarkedTextBackground):
(InlineTextBox::textPos):
(InlineTextBox::offsetForPosition):
(InlineTextBox::positionForOffset):
(RenderText::cacheWidths):
(RenderText::widthFromCache):
(RenderText::trimmedMinMaxWidth):
(RenderText::calcMinMaxWidth):
(RenderText::containsOnlyWhitespace):
(RenderText::width):
* khtml/rendering/render_text.h:
* kwq/KWQFontMetrics.h:
* kwq/KWQFontMetrics.mm:
(QFontMetrics::width):
(QFontMetrics::charWidth):
(QFontMetrics::floatWidth):
(QFontMetrics::floatCharacterWidths):
(QFontMetrics::checkSelectionPoint):
(QFontMetrics::boundingRect):
(QFontMetrics::size):
* kwq/KWQPainter.h:
* kwq/KWQPainter.mm:
(QPainter::drawText):
(QPainter::drawHighlightForText):
* kwq/WebCoreTextRenderer.h:
* kwq/WebCoreTextRendererFactory.mm:
(WebCoreInitializeEmptyTextStyle):
* layout-tests/editing/deleting/delete-tab-001-expected.txt:
* layout-tests/editing/deleting/delete-tab-001.html:
* layout-tests/editing/deleting/delete-tab-002-expected.txt:
* layout-tests/editing/deleting/delete-tab-002.html:
* layout-tests/editing/deleting/delete-tab-003-expected.txt:
* layout-tests/editing/deleting/delete-tab-003.html:
* layout-tests/editing/deleting/delete-tab-004-expected.txt:
* layout-tests/editing/deleting/delete-tab-004.html:
* layout-tests/editing/inserting/insert-tab-001-expected.txt:
* layout-tests/editing/inserting/insert-tab-002-expected.txt:
* layout-tests/editing/inserting/insert-tab-003-expected.txt:
* layout-tests/editing/inserting/insert-tab-004-expected.txt:
* layout-tests/fast/dom/quadraticCurveTo-expected.txt:
* layout-tests/fast/js/string-replace-2-expected.txt:
* layout-tests/fast/table/039-expected.txt:
* layout-tests/fast/table/border-collapsing/004-expected.txt:
* layout-tests/fast/tokenizer/script_extra_close-expected.txt:
2005-06-29 Geoffrey Garen <ggaren@apple.com>
Contributed by Francisco Tolmasky <tolmasky@gmail.com>
......@@ -32,6 +32,7 @@
#include "css/cssparser.h"
#include "css/cssproperties.h"
#include "dom/dom_string.h"
#include "htmlediting.h"
#include "html/html_elementimpl.h"
#include "misc/htmltags.h"
#include "misc/htmlattrs.h"
......@@ -284,7 +285,7 @@ static ElementImpl *createFontElement(DocumentImpl *document)
ElementImpl *createStyleSpanElement(DocumentImpl *document)
{
int exceptionCode = 0;
ElementImpl *styleElement = document->createHTMLElement("SPAN", exceptionCode);
ElementImpl *styleElement = document->createHTMLElement("span", exceptionCode);
ASSERT(exceptionCode == 0);
styleElement->setAttribute(ATTR_CLASS, styleSpanClassString());
return styleElement;
......@@ -678,6 +679,8 @@ void ApplyStyleCommand::removeCSSStyle(CSSMutableStyleDeclarationImpl *style, HT
int propertyID = (*it).id();
CSSValueImpl *value = decl->getPropertyCSSValue(propertyID);
if (value) {
if (propertyID == CSS_PROP_WHITE_SPACE && isTabSpanNode(elem))
continue;
value->ref();
removeCSSProperty(decl, propertyID);
value->deref();
......@@ -1248,6 +1251,10 @@ void ApplyStyleCommand::addInlineStyleIfNeeded(CSSMutableStyleDeclarationImpl *s
StyleChange styleChange(style, Position(startNode, 0), StyleChange::styleModeForParseMode(document()->inCompatMode()));
int exceptionCode = 0;
// Prevent style changes to our tab spans, because it might remove the whitespace:pre we are after
if (isTabSpanTextNode(startNode))
return;
//
// Font tags need to go outside of CSS so that CSS font sizes override leagcy font sizes.
//
......
......@@ -267,7 +267,7 @@ void DeleteSelectionCommand::saveTypingStyleState()
// Figure out the typing style in effect before the delete is done.
// FIXME: Improve typing style.
// See this bug: <rdar://problem/3769899> Implementation of typing style needs improvement
CSSComputedStyleDeclarationImpl *computedStyle = m_selectionToDelete.start().computedStyle();
CSSComputedStyleDeclarationImpl *computedStyle = positionBeforeTabSpan(m_selectionToDelete.start()).computedStyle();
computedStyle->ref();
m_typingStyle = computedStyle->copyInheritableProperties();
m_typingStyle->ref();
......
......@@ -26,6 +26,7 @@
#include "edit_command.h"
#include "selection.h"
#include "khtml_part.h"
#include "htmlediting.h"
#include "xml/dom_position.h"
#include "xml/dom_docimpl.h"
......@@ -389,7 +390,7 @@ bool EditCommand::isTypingCommand() const
CSSMutableStyleDeclarationImpl *EditCommand::styleAtPosition(const Position &pos)
{
CSSComputedStyleDeclarationImpl *computedStyle = pos.computedStyle();
CSSComputedStyleDeclarationImpl *computedStyle = positionBeforeTabSpan(pos).computedStyle();
computedStyle->ref();
CSSMutableStyleDeclarationImpl *style = computedStyle->copyInheritableProperties();
computedStyle->deref();
......
......@@ -32,6 +32,7 @@ class QString;
#define AppleConvertedSpace "Apple-converted-space"
#define ApplePasteAsQuotation "Apple-paste-as-quotation"
#define AppleStyleSpanClass "Apple-style-span"
#define AppleTabSpanClass "Apple-tab-span"
enum EAnnotateForInterchange { DoNotAnnotateForInterchange, AnnotateForInterchange };
......
......@@ -126,8 +126,11 @@ static int maxRangeOffset(NodeImpl *n)
return 1;
}
bool isSpecialElement(NodeImpl *n)
bool isSpecialElement(const NodeImpl *n)
{
if (!n)
return false;
if (!n->isHTMLElement())
return false;
......@@ -138,16 +141,18 @@ bool isSpecialElement(NodeImpl *n)
return true;
RenderObject *renderer = n->renderer();
if (renderer && (renderer->style()->display() == TABLE || renderer->style()->display() == INLINE_TABLE))
if (!renderer)
return false;
if (renderer->style()->display() == TABLE || renderer->style()->display() == INLINE_TABLE)
return true;
if (renderer && renderer->style()->isFloating())
if (renderer->style()->isFloating())
return true;
if (renderer && renderer->style()->position() != STATIC)
if (renderer->style()->position() != STATIC)
return true;
return false;
}
......@@ -280,6 +285,50 @@ ElementImpl *createBreakElement(DocumentImpl *document)
return breakNode;
}
bool isTabSpanNode(const NodeImpl *node)
{
return (node && node->isElementNode() && static_cast<const ElementImpl *>(node)->getAttribute("class") == AppleTabSpanClass);
}
bool isTabSpanTextNode(const NodeImpl *node)
{
return (node && node->parentNode() && isTabSpanNode(node->parentNode()));
}
Position positionBeforeTabSpan(const Position& pos)
{
NodeImpl *node = pos.node();
if (isTabSpanTextNode(node))
node = node->parent();
else if (!isTabSpanNode(node))
return pos;
return Position(node->parentNode(), node->nodeIndex());
}
ElementImpl *createTabSpanElement(DocumentImpl *document, NodeImpl *tabTextNode)
{
// make the span to hold the tab
int exceptionCode = 0;
ElementImpl *spanElement = document->createHTMLElement("span", exceptionCode);
assert(exceptionCode == 0);
spanElement->setAttribute(ATTR_CLASS, AppleTabSpanClass);
spanElement->setAttribute(ATTR_STYLE, "white-space:pre");
// add tab text to that span
if (!tabTextNode)
tabTextNode = document->createEditingTextNode("\t");
spanElement->appendChild(tabTextNode, exceptionCode);
assert(exceptionCode == 0);
return spanElement;
}
ElementImpl *createTabSpanElement(DocumentImpl *document, QString *tabText)
{
return createTabSpanElement(document, document->createTextNode(*tabText));
}
bool isNodeRendered(const NodeImpl *node)
{
if (!node)
......
......@@ -58,15 +58,21 @@ void derefNodesInList(QPtrList<DOM::NodeImpl> &list);
//------------------------------------------------------------------------------------------
bool isSpecialElement(const DOM::NodeImpl *n);
DOM::ElementImpl *createDefaultParagraphElement(DOM::DocumentImpl *document);
DOM::ElementImpl *createBreakElement(DOM::DocumentImpl *document);
bool isTabSpanNode(const DOM::NodeImpl *node);
bool isTabSpanTextNode(const DOM::NodeImpl *node);
DOM::Position positionBeforeTabSpan(const DOM::Position& pos);
DOM::ElementImpl *createTabSpanElement(DOM::DocumentImpl *document, DOM::NodeImpl *tabTextNode=0);
DOM::ElementImpl *createTabSpanElement(DOM::DocumentImpl *document, QString *tabText);
bool isNodeRendered(const DOM::NodeImpl *);
bool isMailBlockquote(const DOM::NodeImpl *);
DOM::NodeImpl *nearestMailBlockquote(const DOM::NodeImpl *);
bool isSpecialElement(DOM::NodeImpl *n);
//------------------------------------------------------------------------------------------
bool isTableStructureNode(const DOM::NodeImpl *node);
......
......@@ -27,9 +27,11 @@
#include "khtml_part.h"
#include "htmlediting.h"
#include "html_interchange.h"
#include "visible_position.h"
#include "visible_text.h"
#include "visible_units.h"
#include "misc/htmlattrs.h"
#include "xml/dom_docimpl.h"
#include "xml/dom_position.h"
#include "xml/dom_textimpl.h"
......@@ -60,23 +62,10 @@ void InsertTextCommand::doApply()
{