Have is<>(T*) function do a null check on the pointer argument
[WebKit-https.git] / Source / WebKit / mac / WebView / WebRenderLayer.mm
1 /*
2  * Copyright (C) 2010 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  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #import "WebRenderLayer.h"
27
28 #import "WebFrameInternal.h"
29 #import <WebCore/Frame.h>
30 #import <WebCore/FrameLoader.h>
31 #import <WebCore/FrameLoaderClient.h>
32 #import <WebCore/RenderLayer.h>
33 #import <WebCore/RenderLayerBacking.h>
34 #import <WebCore/RenderView.h>
35 #import <WebCore/StyledElement.h>
36 #import <wtf/text/StringBuilder.h>
37 #import <wtf/text/WTFString.h>
38
39 using namespace WebCore;
40
41 @interface WebRenderLayer(Private)
42
43 - (id)initWithRenderLayer:(RenderLayer *)layer;
44 - (void)buildDescendantLayers:(RenderLayer*)rootLayer;
45
46 @end
47
48 @implementation WebRenderLayer
49
50 + (NSString *)nameForLayer:(RenderLayer*)layer
51 {
52     const RenderObject& renderer = layer->renderer();
53     NSString *name = [NSString stringWithUTF8String:renderer.renderName()];
54
55     if (Element* element = is<Element>(renderer.node()) ? downcast<Element>(renderer.node()) : nullptr) {
56         name = [name stringByAppendingFormat:@" %@", (NSString *)element->tagName()];
57         if (element->hasID())
58             name = [name stringByAppendingFormat:@" id=\"%@\"", (NSString *)element->getIdAttribute()];
59
60         if (element->hasClass()) {
61             StringBuilder classes;
62             for (size_t i = 0; i < element->classNames().size(); ++i) {
63                 if (i > 0)
64                     classes.append(' ');
65                 classes.append(element->classNames()[i]);
66             }
67             name = [name stringByAppendingFormat:@" class=\"%@\"", (NSString *)classes.toString()];
68         }
69     }
70
71     if (layer->isReflection())
72         name = [name stringByAppendingString:@" (reflection)"];
73
74     return name;
75 }
76
77 + (NSString *)compositingInfoForLayer:(RenderLayer*)layer
78 {
79     if (!layer->isComposited())
80         return @"";
81
82     NSString *layerType = @"";
83     RenderLayerBacking* backing = layer->backing();
84     switch (backing->compositingLayerType()) {
85         case NormalCompositingLayer:
86             layerType = @"composited";
87             break;
88         case TiledCompositingLayer:
89             layerType = @"composited: tiled layer";
90             break;
91         case MediaCompositingLayer:
92             layerType = @"composited for plug-in, video or WebGL";
93             break;
94         case ContainerCompositingLayer:
95             layerType = @"composited: container layer";
96             break;
97     }
98     
99     if (backing->hasClippingLayer())
100         layerType = [layerType stringByAppendingString:@" (clipping)"];
101
102     if (backing->hasAncestorClippingLayer())
103         layerType = [layerType stringByAppendingString:@" (clipped)"];
104
105     return layerType;
106 }
107
108 - (id)initWithRenderLayer:(RenderLayer*)layer
109 {
110     if ((self = [super init])) {
111         name = [[WebRenderLayer nameForLayer:layer] retain];
112         bounds = layer->absoluteBoundingBox();
113         composited = layer->isComposited();
114         compositingInfo = [[WebRenderLayer compositingInfoForLayer:layer] retain];
115     }
116
117     return self;
118 }
119
120 - (id)initWithName:(NSString*)layerName
121 {
122     if ((self = [super init])) {
123         name = [layerName copy];
124         separator = YES;
125     }
126
127     return self;
128 }
129
130 // Only called on the root.
131 - (id)initWithWebFrame:(WebFrame *)webFrame
132 {
133     self = [super init];
134     
135     Frame* frame = core(webFrame);
136     if (!frame->loader().client().hasHTMLView()) {
137         [self release];
138         return nil;
139     }
140     
141     RenderObject* renderer = frame->contentRenderer();
142     if (!renderer) {
143         [self release];
144         return nil;
145     }
146
147     if (renderer->hasLayer()) {
148         RenderLayer* layer = toRenderBoxModelObject(renderer)->layer();
149
150         name = [[WebRenderLayer nameForLayer:layer] retain];
151         bounds = layer->absoluteBoundingBox();
152         composited = layer->isComposited();
153         compositingInfo = [[WebRenderLayer compositingInfoForLayer:layer] retain];
154     
155         [self buildDescendantLayers:layer];
156     }
157     
158     return self;
159 }
160
161 - (void)dealloc
162 {
163     [children release];
164     [name release];
165     [compositingInfo release];
166     [super dealloc];
167 }
168
169 - (void)buildDescendantLayers:(RenderLayer*)layer
170 {
171     NSMutableArray *childWebLayers = [[NSMutableArray alloc] init];
172
173     // Build children in back to front order.
174     
175     if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
176         size_t listSize = negZOrderList->size();
177
178         if (listSize) {
179             WebRenderLayer* newLayer = [[WebRenderLayer alloc] initWithName:@"-ve z-order list"];
180             [childWebLayers addObject:newLayer];
181             [newLayer release];
182         }
183
184         for (size_t i = 0; i < listSize; ++i) {
185             RenderLayer* curLayer = negZOrderList->at(i);
186
187             WebRenderLayer* newLayer = [[WebRenderLayer alloc] initWithRenderLayer:curLayer];
188             [newLayer buildDescendantLayers:curLayer];
189
190             [childWebLayers addObject:newLayer];
191             [newLayer release];
192         }
193     }
194
195     if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
196         size_t listSize = normalFlowList->size();
197
198         if (listSize) {
199             WebRenderLayer* newLayer = [[WebRenderLayer alloc] initWithName:@"normal flow list"];
200             [childWebLayers addObject:newLayer];
201             [newLayer release];
202         }
203         
204         for (size_t i = 0; i < listSize; ++i) {
205             RenderLayer* curLayer = normalFlowList->at(i);
206
207             WebRenderLayer* newLayer = [[WebRenderLayer alloc] initWithRenderLayer:curLayer];
208             [newLayer buildDescendantLayers:curLayer];
209
210             [childWebLayers addObject:newLayer];
211             [newLayer release];
212         }
213     }
214
215     if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
216         size_t listSize = posZOrderList->size();
217
218         if (listSize) {
219             WebRenderLayer* newLayer = [[WebRenderLayer alloc] initWithName:@"+ve z-order list"];
220             [childWebLayers addObject:newLayer];
221             [newLayer release];
222         }
223
224         for (size_t i = 0; i < listSize; ++i) {
225             RenderLayer* curLayer = posZOrderList->at(i);
226
227             WebRenderLayer* newLayer = [[WebRenderLayer alloc] initWithRenderLayer:curLayer];
228             [newLayer buildDescendantLayers:curLayer];
229
230             [childWebLayers addObject:newLayer];
231             [newLayer release];
232         }
233     }
234
235     children = childWebLayers;
236 }
237
238 - (NSArray *)children
239 {
240     return children;
241 }
242
243 - (NSString *)name
244 {
245     return name;
246 }
247
248 - (NSString *)positionString
249 {
250     return [NSString stringWithFormat:@"(%.0f, %.0f)", bounds.origin.x, bounds.origin.y];
251 }
252
253 - (NSString *)widthString
254 {
255     return [NSString stringWithFormat:@"%.0f", bounds.size.width];
256 }
257
258 - (NSString *)heightString
259 {
260     return [NSString stringWithFormat:@"%.0f", bounds.size.height];
261 }
262
263 - (NSString *)compositingInfo
264 {
265     return compositingInfo;
266 }
267
268 - (BOOL)isComposited
269 {
270     return composited;
271 }
272
273 - (BOOL)isSeparator
274 {
275     return separator;
276 }
277
278 @end