• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (C) 2005, 2007 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 "WebBackForwardList.h"
30#import "WebBackForwardListInternal.h"
31
32#import "WebFrameInternal.h"
33#import "WebHistoryItemInternal.h"
34#import "WebHistoryItemPrivate.h"
35#import "WebKitLogging.h"
36#import "WebNSObjectExtras.h"
37#import "WebPreferencesPrivate.h"
38#import "WebTypesInternal.h"
39#import "WebViewPrivate.h"
40#import <WebCore/BackForwardList.h>
41#import <WebCore/HistoryItem.h>
42#import <WebCore/Page.h>
43#import <WebCore/PageCache.h>
44#import <WebCore/Settings.h>
45#import <WebCore/ThreadCheck.h>
46#import <WebCore/WebCoreObjCExtras.h>
47#import <runtime/InitializeThreading.h>
48#import <wtf/Assertions.h>
49#import <wtf/RetainPtr.h>
50#import <wtf/StdLibExtras.h>
51
52using namespace WebCore;
53
54typedef HashMap<BackForwardList*, WebBackForwardList*> BackForwardListMap;
55
56static BackForwardListMap& backForwardLists()
57{
58    DEFINE_STATIC_LOCAL(BackForwardListMap, staticBackForwardLists, ());
59    return staticBackForwardLists;
60}
61
62@implementation WebBackForwardList (WebBackForwardListInternal)
63
64BackForwardList* core(WebBackForwardList *webBackForwardList)
65{
66    if (!webBackForwardList)
67        return 0;
68
69    return reinterpret_cast<BackForwardList*>(webBackForwardList->_private);
70}
71
72WebBackForwardList *kit(BackForwardList* backForwardList)
73{
74    if (!backForwardList)
75        return nil;
76
77    if (WebBackForwardList *webBackForwardList = backForwardLists().get(backForwardList))
78        return webBackForwardList;
79
80    return [[[WebBackForwardList alloc] initWithBackForwardList:backForwardList] autorelease];
81}
82
83- (id)initWithBackForwardList:(PassRefPtr<BackForwardList>)backForwardList
84{
85    WebCoreThreadViolationCheck();
86    self = [super init];
87    if (!self)
88        return nil;
89
90    _private = reinterpret_cast<WebBackForwardListPrivate*>(backForwardList.releaseRef());
91    backForwardLists().set(core(self), self);
92    return self;
93}
94
95@end
96
97@implementation WebBackForwardList
98
99+ (void)initialize
100{
101    JSC::initializeThreading();
102#ifndef BUILDING_ON_TIGER
103    WebCoreObjCFinalizeOnMainThread(self);
104#endif
105}
106
107- (id)init
108{
109    return [self initWithBackForwardList:BackForwardList::create(0)];
110}
111
112- (void)dealloc
113{
114    if (WebCoreObjCScheduleDeallocateOnMainThread([WebBackForwardList class], self))
115        return;
116
117    BackForwardList* backForwardList = core(self);
118    ASSERT(backForwardList->closed());
119    backForwardLists().remove(backForwardList);
120    backForwardList->deref();
121
122    [super dealloc];
123}
124
125- (void)finalize
126{
127    WebCoreThreadViolationCheck();
128    BackForwardList* backForwardList = core(self);
129    ASSERT(backForwardList->closed());
130    backForwardLists().remove(backForwardList);
131    backForwardList->deref();
132
133    [super finalize];
134}
135
136- (void)_close
137{
138    core(self)->close();
139}
140
141- (void)addItem:(WebHistoryItem *)entry;
142{
143    core(self)->addItem(core(entry));
144
145    // Since the assumed contract with WebBackForwardList is that it retains its WebHistoryItems,
146    // the following line prevents a whole class of problems where a history item will be created in
147    // a function, added to the BFlist, then used in the rest of that function.
148    [[entry retain] autorelease];
149}
150
151- (void)removeItem:(WebHistoryItem *)item
152{
153    core(self)->removeItem(core(item));
154}
155
156- (BOOL)containsItem:(WebHistoryItem *)item
157{
158    return core(self)->containsItem(core(item));
159}
160
161- (void)goBack
162{
163    core(self)->goBack();
164}
165
166- (void)goForward
167{
168    core(self)->goForward();
169}
170
171- (void)goToItem:(WebHistoryItem *)item
172{
173    core(self)->goToItem(core(item));
174}
175
176- (WebHistoryItem *)backItem
177{
178    return [[kit(core(self)->backItem()) retain] autorelease];
179}
180
181- (WebHistoryItem *)currentItem
182{
183    return [[kit(core(self)->currentItem()) retain] autorelease];
184}
185
186- (WebHistoryItem *)forwardItem
187{
188    return [[kit(core(self)->forwardItem()) retain] autorelease];
189}
190
191static NSArray* vectorToNSArray(HistoryItemVector& list)
192{
193    unsigned size = list.size();
194    NSMutableArray *result = [[[NSMutableArray alloc] initWithCapacity:size] autorelease];
195    for (unsigned i = 0; i < size; ++i)
196        [result addObject:kit(list[i].get())];
197
198    return result;
199}
200
201- (NSArray *)backListWithLimit:(int)limit;
202{
203    HistoryItemVector list;
204    core(self)->backListWithLimit(limit, list);
205    return vectorToNSArray(list);
206}
207
208- (NSArray *)forwardListWithLimit:(int)limit;
209{
210    HistoryItemVector list;
211    core(self)->forwardListWithLimit(limit, list);
212    return vectorToNSArray(list);
213}
214
215- (int)capacity
216{
217    return core(self)->capacity();
218}
219
220- (void)setCapacity:(int)size
221{
222    core(self)->setCapacity(size);
223}
224
225
226-(NSString *)description
227{
228    NSMutableString *result;
229
230    result = [NSMutableString stringWithCapacity:512];
231
232    [result appendString:@"\n--------------------------------------------\n"];
233    [result appendString:@"WebBackForwardList:\n"];
234
235    BackForwardList* backForwardList = core(self);
236    HistoryItemVector& entries = backForwardList->entries();
237
238    unsigned size = entries.size();
239    for (unsigned i = 0; i < size; ++i) {
240        if (entries[i] == backForwardList->currentItem()) {
241            [result appendString:@" >>>"];
242        } else {
243            [result appendString:@"    "];
244        }
245        [result appendFormat:@"%2d) ", i];
246        int currPos = [result length];
247        [result appendString:[kit(entries[i].get()) description]];
248
249        // shift all the contents over.  a bit slow, but this is for debugging
250        NSRange replRange = {currPos, [result length]-currPos};
251        [result replaceOccurrencesOfString:@"\n" withString:@"\n        " options:0 range:replRange];
252
253        [result appendString:@"\n"];
254    }
255
256    [result appendString:@"\n--------------------------------------------\n"];
257
258    return result;
259}
260
261- (void)setPageCacheSize:(NSUInteger)size
262{
263    [kit(core(self)->page()) setUsesPageCache:size != 0];
264}
265
266- (NSUInteger)pageCacheSize
267{
268    return [kit(core(self)->page()) usesPageCache] ? pageCache()->capacity() : 0;
269}
270
271- (int)backListCount
272{
273    return core(self)->backListCount();
274}
275
276- (int)forwardListCount
277{
278    return core(self)->forwardListCount();
279}
280
281- (WebHistoryItem *)itemAtIndex:(int)index
282{
283    return [[kit(core(self)->itemAtIndex(index)) retain] autorelease];
284}
285
286@end
287