LayoutTests:
authorharrison <harrison@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 29 Sep 2006 16:57:38 +0000 (16:57 +0000)
committerharrison <harrison@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 29 Sep 2006 16:57:38 +0000 (16:57 +0000)
        Reviewed by John Sullivan.

        <rdar://problem/4663772> REGRESSION: Cannot type in Japanese after replying to a particular message
        <rdar://problem/4673293> REGRESSION: Can't enter the Japanese characters in Mail or Blot

        * fast/text/attributed-substring-from-range-001-expected.txt: Added.
        * fast/text/attributed-substring-from-range-001.html: Added.

        Check attributed string results when starting or ending at a br element.

WebCore:

        Reviewed by John Sullivan.

        <rdar://problem/4663772> REGRESSION: Cannot type in Japanese after replying to a particular message
        <rdar://problem/4673293> REGRESSION: Can't enter the Japanese characters in Mail or Blot

        Test added
        * fast/text/attributed-substring-from-range-001.html

        * bridge/mac/FrameMac.mm:
        (WebCore::FrameMac::attributedString):
        Handle non-zero offsets when start and/or end node is a container. Offset used to be ignored in this case.
        Also, add validation of the range.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@16642 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/fast/text/attributed-substring-from-range-001-expected.txt [new file with mode: 0644]
LayoutTests/fast/text/attributed-substring-from-range-001.html [new file with mode: 0644]
WebCore/ChangeLog
WebCore/bridge/mac/FrameMac.mm

index e8bc6f5af3c9c1daaf7e833ee227bd4d83981f07..d58f19d7ef80904fdba585a11a1c62fa0c5a436a 100644 (file)
@@ -1,3 +1,15 @@
+2006-09-29  David Harrison  <harrison@apple.com>
+
+        Reviewed by John Sullivan.
+
+        <rdar://problem/4663772> REGRESSION: Cannot type in Japanese after replying to a particular message
+        <rdar://problem/4673293> REGRESSION: Can't enter the Japanese characters in Mail or Blot
+
+        * fast/text/attributed-substring-from-range-001-expected.txt: Added.
+        * fast/text/attributed-substring-from-range-001.html: Added.
+        
+        Check attributed string results when starting or ending at a br element.
+
 2006-09-29  Rob Buis  <buis@kde.org>
 
         Reviewed by Maciej.
diff --git a/LayoutTests/fast/text/attributed-substring-from-range-001-expected.txt b/LayoutTests/fast/text/attributed-substring-from-range-001-expected.txt
new file mode 100644 (file)
index 0000000..cdfbcb0
--- /dev/null
@@ -0,0 +1,18 @@
+EDITING DELEGATE: shouldBeginEditingInDOMRange:range from 0 of BODY > HTML > #document to 5 of BODY > HTML > #document
+EDITING DELEGATE: webViewDidBeginEditing:WebViewDidBeginEditingNotification
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+Testing text with br elements (<div><br></div>hello<br>)
+(0, 0):
+(0, 1): {}
+(0, 2): {}h{ NSColor = NSCalibratedWhiteColorSpace 0 1; NSFont = "Times-Roman 16.00 pt. S [] (0xXXXXXXXX) fobj=0xXXXXXXXX, spc=4.00"; }
+(1, 1): h{ NSColor = NSCalibratedWhiteColorSpace 0 1; NSFont = "Times-Roman 16.00 pt. S [] (0xXXXXXXXX) fobj=0xXXXXXXXX, spc=4.00"; }
+(1, 5): hello{ NSColor = NSCalibratedWhiteColorSpace 0 1; NSFont = "Times-Roman 16.00 pt. S [] (0xXXXXXXXX) fobj=0xXXXXXXXX, spc=4.00"; }
+(1, 6): hello{ NSColor = NSCalibratedWhiteColorSpace 0 1; NSFont = "Times-Roman 16.00 pt. S [] (0xXXXXXXXX) fobj=0xXXXXXXXX, spc=4.00"; } {}
+(1, 100): hello{ NSColor = NSCalibratedWhiteColorSpace 0 1; NSFont = "Times-Roman 16.00 pt. S [] (0xXXXXXXXX) fobj=0xXXXXXXXX, spc=4.00"; } {}
+(6, 1): {}
+(7, 1):
+(100, 0): undefined
+(100, 100): undefined
+
+
diff --git a/LayoutTests/fast/text/attributed-substring-from-range-001.html b/LayoutTests/fast/text/attributed-substring-from-range-001.html
new file mode 100644 (file)
index 0000000..39898d5
--- /dev/null
@@ -0,0 +1,55 @@
+<html>
+<head>
+<style>
+body { margin: 10; padding: 0 }
+</style>
+</head>
+<body contenteditable><div><br></div>hello<br>
+<script type="text/javascript">
+
+    var console_messages = document.createElement("ol");
+    
+    function log(message)
+    {
+        var item = document.createElement("li");
+        item.appendChild(document.createTextNode(String(message).replace(/0x[0-9a-fA-F]{8}/g, "0xXXXXXXXX")));
+        console_messages.appendChild(item);
+    }
+    
+    if (window.layoutTestController) {
+        
+        try {
+        
+            layoutTestController.dumpAsText();
+        
+            log("Testing text with br elements (<div><br></div>hello<br>)");
+            window.getSelection().setPosition(document.body, 5);
+
+            log("(0, 0): " + textInputController.attributedSubstringFromRange(0, 0));
+            log("(0, 1): " + textInputController.attributedSubstringFromRange(0, 1));
+            log("(0, 2): " + textInputController.attributedSubstringFromRange(0, 2));
+            log("(1, 1): " + textInputController.attributedSubstringFromRange(1, 1));
+            log("(1, 5): " + textInputController.attributedSubstringFromRange(1, 5));
+            log("(1, 6): " + textInputController.attributedSubstringFromRange(1, 6));
+            log("(1, 100): " + textInputController.attributedSubstringFromRange(1, 100));
+            log("(6, 1): " + textInputController.attributedSubstringFromRange(6, 1));
+            log("(7, 1): " + textInputController.attributedSubstringFromRange(7, 1)); // should be empty
+            log("(100, 0): " + textInputController.attributedSubstringFromRange(100, 0)); // should be undefined
+            log("(100, 100): " + textInputController.attributedSubstringFromRange(100, 100)); // should be undefined
+            
+            document.body.innerHTML = "";
+
+        } catch (ex) {
+            log("Exception: " + ex.description);
+        }
+        
+        var console = document.createElement("p");
+        console.appendChild(console_messages);
+        document.body.appendChild(console);
+        
+    } else {
+        document.write("This testcase is buggy: 9337.  (cannot run interactively)");
+    }
+</script>
+</body>
+</html>
index 391cadc7a0338772aad5a2c2bd500127c5d6e149..3a547177c9a6977d29721e521b39bdef1db7bd50 100644 (file)
@@ -1,3 +1,18 @@
+2006-09-29  David Harrison  <harrison@apple.com>
+
+        Reviewed by John Sullivan.
+
+        <rdar://problem/4663772> REGRESSION: Cannot type in Japanese after replying to a particular message
+        <rdar://problem/4673293> REGRESSION: Can't enter the Japanese characters in Mail or Blot
+
+        Test added
+        * fast/text/attributed-substring-from-range-001.html
+
+        * bridge/mac/FrameMac.mm:
+        (WebCore::FrameMac::attributedString):
+        Handle non-zero offsets when start and/or end node is a container. Offset used to be ignored in this case.
+        Also, add validation of the range.
+
 2006-09-29  Rob Buis  <buis@kde.org>
 
         Reviewed by Maciej.
index 2d7c594a1f458b0653616e36c1d89de3b7a79021..6782bfad8fd2dc1af89981817b92130bd5cb2222 100644 (file)
@@ -2220,25 +2220,29 @@ static Node* isTextFirstInListItem(Node *e)
     return 0;
 }
 
-// FIXME: This collosal function needs to be refactored into maintainable smaller bits.
+// FIXME: Enhance TextIterator to optionally add attributes, then just call through to that.
 
 #define BULLET_CHAR 0x2022
 #define SQUARE_CHAR 0x25AA
 #define CIRCLE_CHAR 0x25E6
 
-NSAttributedString *FrameMac::attributedString(Node *_start, int startOffset, Node *endNode, int endOffset)
+NSAttributedString *FrameMac::attributedString(Node *startNode, int startOffset, Node *endNode, int endOffset)
 {
     ListItemInfo info;
     NSMutableAttributedString *result;
     BEGIN_BLOCK_OBJC_EXCEPTIONS;
 
-    Node * _startNode = _start;
-
-    if (!_startNode)
+    Range range(document(), startNode, startOffset, endNode, endOffset);
+    if (!range.boundaryPointsValid())
         return nil;
-
+    
+    Node* firstNode = range.startNode();
+    if (!firstNode)
+        return nil;
+    Node* pastEndNode = range.pastEndNode();
+    
     result = [[[NSMutableAttributedString alloc] init] autorelease];
-
+    
     bool hasNewLine = true;
     bool addedSpace = true;
     NSAttributedString *pendingStyledSpace = nil;
@@ -2249,25 +2253,25 @@ NSAttributedString *FrameMac::attributedString(Node *_start, int startOffset, No
     Vector<ListItemInfo> listItemLocations;
     float maxMarkerWidth = 0;
     
-    Node *n = _startNode;
+    Node *currentNode = firstNode;
     
     // If the first item is the entire text of a list item, use the list item node as the start of the 
     // selection, not the text node.  The user's intent was probably to select the list.
-    if (n->isTextNode() && startOffset == 0) {
-        Node *startListNode = isTextFirstInListItem(_startNode);
+    if (currentNode->isTextNode() && startOffset == 0) {
+        Node *startListNode = isTextFirstInListItem(firstNode);
         if (startListNode){
-            _startNode = startListNode;
-            n = _startNode;
+            firstNode = startListNode;
+            currentNode = firstNode;
         }
     }
     
-    while (n) {
-        RenderObject *renderer = n->renderer();
+    while (currentNode && currentNode != pastEndNode) {
+        RenderObject *renderer = currentNode->renderer();
         if (renderer) {
             RenderStyle *style = renderer->style();
             NSFont *font = style->font().primaryFont()->getNSFont();
             bool needSpace = pendingStyledSpace != nil;
-            if (n->isTextNode()) {
+            if (currentNode->isTextNode()) {
                 if (hasNewLine) {
                     addedSpace = true;
                     needSpace = false;
@@ -2276,9 +2280,9 @@ NSAttributedString *FrameMac::attributedString(Node *_start, int startOffset, No
                     hasNewLine = false;
                 }
                 DeprecatedString text;
-                DeprecatedString str = n->nodeValue().deprecatedString();
-                int start = (n == _startNode) ? startOffset : -1;
-                int end = (n == endNode) ? endOffset : -1;
+                DeprecatedString str = currentNode->nodeValue().deprecatedString();
+                int start = (currentNode == firstNode) ? startOffset : -1;
+                int end = (currentNode == endNode) ? endOffset : -1;
                 if (renderer->isText()) {
                     if (!style->collapseWhiteSpace()) {
                         if (needSpace && !addedSpace) {
@@ -2363,24 +2367,24 @@ NSAttributedString *FrameMac::attributedString(Node *_start, int startOffset, No
             } else {
                 // This is our simple HTML -> ASCII transformation:
                 DeprecatedString text;
-                if (n->hasTagName(aTag)) {
+                if (currentNode->hasTagName(aTag)) {
                     // Note the start of the <a> element.  We will add the NSLinkAttributeName
                     // attribute to the attributed string when navigating to the next sibling 
                     // of this node.
                     linkStartLocation = [result length];
-                    linkStartNode = static_cast<Element*>(n);
-                } else if (n->hasTagName(brTag)) {
+                    linkStartNode = static_cast<Element*>(currentNode);
+                } else if (currentNode->hasTagName(brTag)) {
                     text += "\n";
                     hasNewLine = true;
-                } else if (n->hasTagName(liTag)) {
+                } else if (currentNode->hasTagName(liTag)) {
                     DeprecatedString listText;
-                    Element *itemParent = listParent(static_cast<Element*>(n));
+                    Element *itemParent = listParent(static_cast<Element*>(currentNode));
                     
                     if (!hasNewLine)
                         listText += '\n';
                     hasNewLine = true;
 
-                    listItems.append(static_cast<Element*>(n));
+                    listItems.append(static_cast<Element*>(currentNode));
                     info.start = [result length];
                     info.end = 0;
                     listItemLocations.append (info);
@@ -2425,31 +2429,31 @@ NSAttributedString *FrameMac::attributedString(Node *_start, int startOffset, No
                         [result appendAttributedString: partialString];                
                         [partialString release];
                     }
-                } else if (n->hasTagName(olTag) || n->hasTagName(ulTag)) {
+                } else if (currentNode->hasTagName(olTag) || currentNode->hasTagName(ulTag)) {
                     if (!hasNewLine)
                         text += "\n";
                     hasNewLine = true;
-                } else if (n->hasTagName(blockquoteTag)
-                        || n->hasTagName(ddTag)
-                        || n->hasTagName(divTag)
-                        || n->hasTagName(dlTag)
-                        || n->hasTagName(dtTag)
-                        || n->hasTagName(hrTag)
-                        || n->hasTagName(listingTag)
-                        || n->hasTagName(preTag)
-                        || n->hasTagName(tdTag)
-                        || n->hasTagName(thTag)) {
+                } else if (currentNode->hasTagName(blockquoteTag)
+                        || currentNode->hasTagName(ddTag)
+                        || currentNode->hasTagName(divTag)
+                        || currentNode->hasTagName(dlTag)
+                        || currentNode->hasTagName(dtTag)
+                        || currentNode->hasTagName(hrTag)
+                        || currentNode->hasTagName(listingTag)
+                        || currentNode->hasTagName(preTag)
+                        || currentNode->hasTagName(tdTag)
+                        || currentNode->hasTagName(thTag)) {
                     if (!hasNewLine)
                         text += '\n';
                     hasNewLine = true;
-                } else if (n->hasTagName(h1Tag)
-                        || n->hasTagName(h2Tag)
-                        || n->hasTagName(h3Tag)
-                        || n->hasTagName(h4Tag)
-                        || n->hasTagName(h5Tag)
-                        || n->hasTagName(h6Tag)
-                        || n->hasTagName(pTag)
-                        || n->hasTagName(trTag)) {
+                } else if (currentNode->hasTagName(h1Tag)
+                        || currentNode->hasTagName(h2Tag)
+                        || currentNode->hasTagName(h3Tag)
+                        || currentNode->hasTagName(h4Tag)
+                        || currentNode->hasTagName(h5Tag)
+                        || currentNode->hasTagName(h6Tag)
+                        || currentNode->hasTagName(pTag)
+                        || currentNode->hasTagName(trTag)) {
                     if (!hasNewLine)
                         text += '\n';
                     
@@ -2465,7 +2469,7 @@ NSAttributedString *FrameMac::attributedString(Node *_start, int startOffset, No
                     
                     hasNewLine = true;
                 }
-                else if (n->hasTagName(imgTag)) {
+                else if (currentNode->hasTagName(imgTag)) {
                     if (pendingStyledSpace != nil) {
                         if (linkStartLocation == [result length])
                             ++linkStartLocation;
@@ -2473,7 +2477,7 @@ NSAttributedString *FrameMac::attributedString(Node *_start, int startOffset, No
                         [pendingStyledSpace release];
                         pendingStyledSpace = nil;
                     }
-                    NSFileWrapper *fileWrapper = fileWrapperForElement(static_cast<Element*>(n));
+                    NSFileWrapper *fileWrapper = fileWrapperForElement(static_cast<Element*>(currentNode));
                     NSTextAttachment *attachment = [[NSTextAttachment alloc] initWithFileWrapper:fileWrapper];
                     NSAttributedString *iString = [NSAttributedString attributedStringWithAttachment:attachment];
                     [result appendAttributedString: iString];
@@ -2486,25 +2490,22 @@ NSAttributedString *FrameMac::attributedString(Node *_start, int startOffset, No
             }
         }
 
-        if (n == endNode)
-            break;
-
-        Node *next = n->firstChild();
-        if (!next)
-            next = n->nextSibling();
+        Node *nextNode = currentNode->firstChild();
+        if (!nextNode)
+            nextNode = currentNode->nextSibling();
 
-        while (!next && n->parentNode()) {
+        while (!nextNode && currentNode->parentNode()) {
             DeprecatedString text;
-            n = n->parentNode();
-            if (n == endNode)
+            currentNode = currentNode->parentNode();
+            if (currentNode == pastEndNode)
                 break;
-            next = n->nextSibling();
+            nextNode = currentNode->nextSibling();
 
-            if (n->hasTagName(aTag)) {
+            if (currentNode->hasTagName(aTag)) {
                 // End of a <a> element.  Create an attributed string NSLinkAttributeName attribute
                 // for the range of the link.  Note that we create the attributed string from the DOM, which
                 // will have corrected any illegally nested <a> elements.
-                if (linkStartNode && n == linkStartNode) {
+                if (linkStartNode && currentNode == linkStartNode) {
                     String href = parseURL(linkStartNode->getAttribute(hrefAttr));
                     KURL kURL = Mac(linkStartNode->document()->frame())->completeURL(href.deprecatedString());
                     
@@ -2514,15 +2515,15 @@ NSAttributedString *FrameMac::attributedString(Node *_start, int startOffset, No
                     linkStartNode = 0;
                 }
             }
-            else if (n->hasTagName(olTag) || n->hasTagName(ulTag)) {
+            else if (currentNode->hasTagName(olTag) || currentNode->hasTagName(ulTag)) {
                 if (!hasNewLine)
                     text += '\n';
                 hasNewLine = true;
-            } else if (n->hasTagName(liTag)) {
+            } else if (currentNode->hasTagName(liTag)) {
                 
                 int i, count = listItems.size();
                 for (i = 0; i < count; i++){
-                    if (listItems[i] == n){
+                    if (listItems[i] == currentNode){
                         listItemLocations[i].end = [result length];
                         break;
                     }
@@ -2530,27 +2531,27 @@ NSAttributedString *FrameMac::attributedString(Node *_start, int startOffset, No
                 if (!hasNewLine)
                     text += '\n';
                 hasNewLine = true;
-            } else if (n->hasTagName(blockquoteTag) ||
-                       n->hasTagName(ddTag) ||
-                       n->hasTagName(divTag) ||
-                       n->hasTagName(dlTag) ||
-                       n->hasTagName(dtTag) ||
-                       n->hasTagName(hrTag) ||
-                       n->hasTagName(listingTag) ||
-                       n->hasTagName(preTag) ||
-                       n->hasTagName(tdTag) ||
-                       n->hasTagName(thTag)) {
+            } else if (currentNode->hasTagName(blockquoteTag) ||
+                       currentNode->hasTagName(ddTag) ||
+                       currentNode->hasTagName(divTag) ||
+                       currentNode->hasTagName(dlTag) ||
+                       currentNode->hasTagName(dtTag) ||
+                       currentNode->hasTagName(hrTag) ||
+                       currentNode->hasTagName(listingTag) ||
+                       currentNode->hasTagName(preTag) ||
+                       currentNode->hasTagName(tdTag) ||
+                       currentNode->hasTagName(thTag)) {
                 if (!hasNewLine)
                     text += '\n';
                 hasNewLine = true;
-            } else if (n->hasTagName(pTag) ||
-                       n->hasTagName(trTag) ||
-                       n->hasTagName(h1Tag) ||
-                       n->hasTagName(h2Tag) ||
-                       n->hasTagName(h3Tag) ||
-                       n->hasTagName(h4Tag) ||
-                       n->hasTagName(h5Tag) ||
-                       n->hasTagName(h6Tag)) {
+            } else if (currentNode->hasTagName(pTag) ||
+                       currentNode->hasTagName(trTag) ||
+                       currentNode->hasTagName(h1Tag) ||
+                       currentNode->hasTagName(h2Tag) ||
+                       currentNode->hasTagName(h3Tag) ||
+                       currentNode->hasTagName(h4Tag) ||
+                       currentNode->hasTagName(h5Tag) ||
+                       currentNode->hasTagName(h6Tag)) {
                 if (!hasNewLine)
                     text += '\n';
                 // An extra newline is needed at the start, not the end, of these types of tags,
@@ -2563,7 +2564,7 @@ NSAttributedString *FrameMac::attributedString(Node *_start, int startOffset, No
             [partialString release];
         }
 
-        n = next;
+        currentNode = nextNode;
     }
     
     [pendingStyledSpace release];
@@ -2583,7 +2584,7 @@ NSAttributedString *FrameMac::attributedString(Node *_start, int startOffset, No
         // each item in the list (in the resulting attributed string) will be relative to position 
         // of the outermost containing block.
         if (count > 0){
-            containingBlock = _startNode;
+            containingBlock = firstNode;
             while (containingBlock->renderer()->isInline()){
                 containingBlock = containingBlock->parentNode();
             }