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