blob: ef472aa41f4be786bf32f64a59fcc471740b4354 [file] [log] [blame]
/*
* 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 = static_cast<RenderImage*>(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->color().isValid())
[attrs.get() setObject:nsColor(style->color()) forKey:NSForegroundColorAttributeName];
else
[attrs.get() removeObjectForKey:NSForegroundColorAttributeName];
if (style->backgroundColor().isValid())
[attrs.get() setObject:nsColor(style->backgroundColor()) 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