1/*
2 * Copyright (C) 2005, 2008 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1.  Redistributions of source code must retain the above copyright
9 *     notice, this list of conditions and the following disclaimer.
10 * 2.  Redistributions in binary form must reproduce the above copyright
11 *     notice, this list of conditions and the following disclaimer in the
12 *     documentation and/or other materials provided with the distribution.
13 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14 *     its contributors may be used to endorse or promote products derived
15 *     from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#import "WebRenderNode.h"
30
31#import "WebFrameInternal.h"
32#import <WebCore/Frame.h>
33#import <WebCore/FrameLoaderClient.h>
34#import <WebCore/RenderText.h>
35#import <WebCore/RenderWidget.h>
36#import <WebCore/RenderView.h>
37#import <WebCore/Widget.h>
38
39using namespace WebCore;
40
41static WebRenderNode *copyRenderNode(RenderObject*);
42
43@implementation WebRenderNode
44
45- (id)_initWithCoreFrame:(Frame *)frame
46{
47    [self release];
48
49    if (!frame->loader()->client()->hasHTMLView())
50        return nil;
51
52    RenderObject* renderer = frame->contentRenderer();
53    if (!renderer)
54        return nil;
55
56    return copyRenderNode(renderer);
57}
58
59- (id)_initWithName:(NSString *)n position:(NSPoint)p rect:(NSRect)r coreFrame:(Frame*)coreFrame children:(NSArray *)c
60{
61    NSMutableArray *collectChildren;
62
63    self = [super init];
64    if (!self)
65        return nil;
66
67    collectChildren = [c mutableCopy];
68
69    name = [n retain];
70    rect = r;
71    absolutePosition = p;
72
73    if (coreFrame) {
74        WebRenderNode *node = [[WebRenderNode alloc] _initWithCoreFrame:coreFrame];
75        [collectChildren addObject:node];
76        [node release];
77    }
78
79    children = [collectChildren copy];
80    [collectChildren release];
81
82    return self;
83}
84
85static WebRenderNode *copyRenderNode(RenderObject* node)
86{
87    NSMutableArray *children = [[NSMutableArray alloc] init];
88    for (RenderObject* child = node->firstChild(); child; child = child->nextSibling()) {
89        WebRenderNode *childCopy = copyRenderNode(child);
90        [children addObject:childCopy];
91        [childCopy release];
92    }
93
94    NSString *name = [[NSString alloc] initWithUTF8String:node->renderName()];
95
96    RenderWidget* renderWidget = node->isWidget() ? toRenderWidget(node) : 0;
97    Widget* widget = renderWidget ? renderWidget->widget() : 0;
98    FrameView* frameView = widget && widget->isFrameView() ? static_cast<FrameView*>(widget) : 0;
99    Frame* frame = frameView ? frameView->frame() : 0;
100
101    // FIXME: broken with transforms
102    FloatPoint absPos = node->localToAbsolute(FloatPoint());
103    int x = 0;
104    int y = 0;
105    int width = 0;
106    int height = 0;
107    if (node->isBox()) {
108        RenderBox* box = toRenderBox(node);
109        x = box->x();
110        y = box->y();
111        width = box->width();
112        height = box->height();
113    } else if (node->isText()) {
114        // FIXME: Preserve old behavior even though it's strange.
115        RenderText* text = toRenderText(node);
116        x = text->firstRunX();
117        y = text->firstRunY();
118        IntRect box = text->linesBoundingBox();
119        width = box.width();
120        height = box.height();
121    } else if (node->isRenderInline()) {
122        RenderBoxModelObject* inlineFlow = toRenderBoxModelObject(node);
123        IntRect boundingBox = inlineFlow->borderBoundingBox();
124        x = boundingBox.x();
125        y = boundingBox.y();
126        width = boundingBox.width();
127        height = boundingBox.height();
128    }
129
130    WebRenderNode *result = [[WebRenderNode alloc] _initWithName:name
131                                                        position:absPos rect:NSMakeRect(x, y, width, height)
132                                                       coreFrame:frame children:children];
133
134    [name release];
135    [children release];
136
137    return result;
138}
139
140- (id)initWithWebFrame:(WebFrame *)frame
141{
142    return [self _initWithCoreFrame:core(frame)];
143}
144
145- (void)dealloc
146{
147    [children release];
148    [name release];
149    [super dealloc];
150}
151
152- (NSArray *)children
153{
154    return children;
155}
156
157- (NSString *)name
158{
159    return name;
160}
161
162- (NSString *)absolutePositionString
163{
164    return [NSString stringWithFormat:@"(%.0f, %.0f)", absolutePosition.x, absolutePosition.y];
165}
166
167- (NSString *)positionString
168{
169    return [NSString stringWithFormat:@"(%.0f, %.0f)", rect.origin.x, rect.origin.y];
170}
171
172- (NSString *)widthString
173{
174    return [NSString stringWithFormat:@"%.0f", rect.size.width];
175}
176
177- (NSString *)heightString
178{
179    return [NSString stringWithFormat:@"%.0f", rect.size.height];
180}
181
182@end
183