WebKit/mac/Misc/WebNSAttributedStringExtras.mm
changeset 0 4f2f89ce4247
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/WebKit/mac/Misc/WebNSAttributedStringExtras.mm	Fri Sep 17 09:02:29 2010 +0300
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2005, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer. 
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution. 
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "WebNSAttributedStringExtras.h"
+
+#import "DOMRangeInternal.h"
+#import "WebDataSourcePrivate.h"
+#import "WebFrame.h"
+#import "WebFrameInternal.h"
+#import "WebTypesInternal.h"
+#import <WebCore/BlockExceptions.h>
+#import <WebCore/ColorMac.h>
+#import <WebCore/CSSHelper.h>
+#import <WebCore/Document.h>
+#import <WebCore/Element.h>
+#import <WebCore/Frame.h>
+#import <WebCore/FrameLoader.h>
+#import <WebCore/HTMLNames.h>
+#import <WebCore/Image.h>
+#import <WebCore/InlineTextBox.h>
+#import <WebCore/Range.h>
+#import <WebCore/RenderImage.h>
+#import <WebCore/RenderListItem.h>
+#import <WebCore/RenderObject.h>
+#import <WebCore/RenderStyle.h>
+#import <WebCore/RenderText.h>
+#import <WebCore/SimpleFontData.h>
+#import <WebCore/Text.h>
+#import <WebCore/TextIterator.h>
+
+using namespace WebCore;
+using namespace HTMLNames;
+
+struct ListItemInfo {
+    unsigned start;
+    unsigned end;
+};
+
+static NSFileWrapper *fileWrapperForElement(Element* e)
+{
+    NSFileWrapper *wrapper = nil;
+    BEGIN_BLOCK_OBJC_EXCEPTIONS;
+    
+    const AtomicString& attr = e->getAttribute(srcAttr);
+    if (!attr.isEmpty()) {
+        NSURL *URL = e->document()->completeURL(attr);
+        wrapper = [[kit(e->document()->frame()) _dataSource] _fileWrapperForURL:URL];
+    }
+    if (!wrapper) {
+        RenderImage* renderer = toRenderImage(e->renderer());
+        if (renderer->cachedImage() && !renderer->cachedImage()->errorOccurred()) {
+            wrapper = [[NSFileWrapper alloc] initRegularFileWithContents:(NSData *)(renderer->cachedImage()->image()->getTIFFRepresentation())];
+            [wrapper setPreferredFilename:@"image.tiff"];
+            [wrapper autorelease];
+        }
+    }
+
+    return wrapper;
+
+    END_BLOCK_OBJC_EXCEPTIONS;
+
+    return nil;
+}
+
+@implementation NSAttributedString (WebKitExtras)
+
+- (NSAttributedString *)_web_attributedStringByStrippingAttachmentCharacters
+{
+    // This code was originally copied from NSTextView
+    NSRange attachmentRange;
+    NSString *originalString = [self string];
+    static NSString *attachmentCharString = nil;
+    
+    if (!attachmentCharString) {
+        unichar chars[2];
+        if (!attachmentCharString) {
+            chars[0] = NSAttachmentCharacter;
+            chars[1] = 0;
+            attachmentCharString = [[NSString alloc] initWithCharacters:chars length:1];
+        }
+    }
+    
+    attachmentRange = [originalString rangeOfString:attachmentCharString];
+    if (attachmentRange.location != NSNotFound && attachmentRange.length > 0) {
+        NSMutableAttributedString *newAttributedString = [[self mutableCopyWithZone:NULL] autorelease];
+        
+        while (attachmentRange.location != NSNotFound && attachmentRange.length > 0) {
+            [newAttributedString replaceCharactersInRange:attachmentRange withString:@""];
+            attachmentRange = [[newAttributedString string] rangeOfString:attachmentCharString];
+        }
+        return newAttributedString;
+    }
+    
+    return self;
+}
+
++ (NSAttributedString *)_web_attributedStringFromRange:(Range*)range
+{
+    NSMutableAttributedString *string = [[NSMutableAttributedString alloc] init];
+    NSUInteger stringLength = 0;
+    RetainPtr<NSMutableDictionary> attrs(AdoptNS, [[NSMutableDictionary alloc] init]);
+
+    for (TextIterator it(range); !it.atEnd(); it.advance()) {
+        RefPtr<Range> currentTextRange = it.range();
+        ExceptionCode ec = 0;
+        Node* startContainer = currentTextRange->startContainer(ec);
+        Node* endContainer = currentTextRange->endContainer(ec);
+        int startOffset = currentTextRange->startOffset(ec);
+        int endOffset = currentTextRange->endOffset(ec);
+        
+        if (startContainer == endContainer && (startOffset == endOffset - 1)) {
+            Node* node = startContainer->childNode(startOffset);
+            if (node && node->hasTagName(imgTag)) {
+                NSFileWrapper *fileWrapper = fileWrapperForElement(static_cast<Element*>(node));
+                NSTextAttachment *attachment = [[NSTextAttachment alloc] initWithFileWrapper:fileWrapper];
+                [string appendAttributedString:[NSAttributedString attributedStringWithAttachment:attachment]];
+                [attachment release];
+            }
+        }
+
+        int currentTextLength = it.length();
+        if (!currentTextLength)
+            continue;
+
+        RenderObject* renderer = startContainer->renderer();
+        ASSERT(renderer);
+        if (!renderer)
+            continue;
+        RenderStyle* style = renderer->style();
+        NSFont *font = style->font().primaryFont()->getNSFont();
+        [attrs.get() setObject:font forKey:NSFontAttributeName];
+        if (style->visitedDependentColor(CSSPropertyColor).alpha())
+            [attrs.get() setObject:nsColor(style->visitedDependentColor(CSSPropertyColor)) forKey:NSForegroundColorAttributeName];
+        else
+            [attrs.get() removeObjectForKey:NSForegroundColorAttributeName];
+        if (style->visitedDependentColor(CSSPropertyBackgroundColor).alpha())
+            [attrs.get() setObject:nsColor(style->visitedDependentColor(CSSPropertyBackgroundColor)) forKey:NSBackgroundColorAttributeName];
+        else
+            [attrs.get() removeObjectForKey:NSBackgroundColorAttributeName];
+
+        RetainPtr<NSString> substring(AdoptNS, [[NSString alloc] initWithCharactersNoCopy:const_cast<UChar*>(it.characters()) length:currentTextLength freeWhenDone:NO]);
+        [string replaceCharactersInRange:NSMakeRange(stringLength, 0) withString:substring.get()];
+        [string setAttributes:attrs.get() range:NSMakeRange(stringLength, currentTextLength)];
+        stringLength += currentTextLength;
+    }
+
+    return [string autorelease];
+}
+
+@end