Commit 208ea79f authored by harrison's avatar harrison

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

        Test cases added: Existing tab-related basic editing tests were updated.  More complex tests are coming soon.

        <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.

        * khtml/editing/apply_style_command.cpp:
        (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::parseSpecial):
        (khtml::HTMLTokenizer::parseText):
        (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::layoutInlineChildren):
        (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:::RenderFlow):
        (khtml::RenderBlock::setStyle):
        (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::drawRect):
        (QPainter::drawLine):
        (QPainter::drawText):
        (QPainter::drawHighlightForText):
        (_fillRectXX):
        (QPainter::fillRect):
        * 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/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@9963 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 9cbf3719
......@@ -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
......@@ -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
......@@ -28,7 +28,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 (55,0) size 232x18
text run at (55,0) width 69: "PASSED. "
......
2005-07-29 David Harrison <harrison@apple.com>
Reviewed by Dave Hyatt (rendering) and Maciej (editing and performance improvements).
Test cases added: Existing tab-related basic editing tests were updated. More complex tests are coming soon.
<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.
* khtml/editing/apply_style_command.cpp:
(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::parseSpecial):
(khtml::HTMLTokenizer::parseText):
(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::layoutInlineChildren):
(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:::RenderFlow):
(khtml::RenderBlock::setStyle):
(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::drawRect):
(QPainter::drawLine):
(QPainter::drawText):
(QPainter::drawHighlightForText):
(_fillRectXX):
(QPainter::fillRect):
* 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/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-07-29 David Hyatt <hyatt@apple.com>
(1) Fixes khtml-user-select: none to have the following additional behavior (that matches Firefox's implementation of the property as well)
......@@ -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 "htmlnames.h"
#include "rendering/render_object.h"
......@@ -679,6 +680,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();
......@@ -1249,6 +1252,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.
//
......
......@@ -275,7 +275,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 };
......
......@@ -71,6 +71,7 @@ using DOM::DOMStringImpl;
using DOM::DoNotUpdateLayout;
using DOM::EditingTextImpl;
using DOM::ElementImpl;
using DOM::HTMLAttributes;
using DOM::HTMLElementImpl;
using DOM::HTMLImageElementImpl;
using DOM::NamedAttrMapImpl;
......@@ -126,8 +127,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 +142,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 +286,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->createElementNS(HTMLTags::xhtmlNamespaceURI(), "span", exceptionCode);
assert(exceptionCode == 0);
spanElement->setAttribute(HTMLAttributes::classAttr(), AppleTabSpanClass);
spanElement->setAttribute(HTMLAttributes::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,6 +27,7 @@
#include "khtml_part.h"
#include "htmlediting.h"
#include "html_interchange.h"
#include "visible_position.h"
#include "visible_text.h"
#include "visible_units.h"
......@@ -60,23 +61,10 @@ void InsertTextCommand::doApply()
{
}
Position InsertTextCommand::prepareForTextInsertion(bool adjustDownstream)
Position InsertTextCommand::prepareForTextInsertion(const Position& pos)
{
// Prepare for text input by looking at the current position.
// Prepare for text input by looking at the specified position.
// It may be necessary to insert a text node to receive characters.
Selection selection = endingSelection();
ASSERT(selection.isCaret());
Position pos = selection.start();
if (adjustDownstream)
pos = pos.downstream();
else
pos = pos.upstream();
Selection typingStyleRange;
pos = positionOutsideContainingSpecialElement(pos);
if (!pos.node()->isTextNode()) {
NodeImpl *textNode = document()->createEditingTextNode("");
NodeImpl *nodeToInsert = textNode;
......@@ -97,14 +85,35 @@ Position InsertTextCommand::prepareForTextInsertion(bool adjustDownstream)
else
ASSERT_NOT_REACHED();
pos = Position(textNode, 0);
return Position(textNode, 0);