WebBackForwardList.mm 9.1 KB

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