ewk_history.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427
  1. /*
  2. Copyright (C) 2009-2010 ProFUSION embedded systems
  3. Copyright (C) 2009-2010 Samsung Electronics
  4. This library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Library General Public
  6. License as published by the Free Software Foundation; either
  7. version 2 of the License, or (at your option) any later version.
  8. This library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Library General Public License for more details.
  12. You should have received a copy of the GNU Library General Public License
  13. along with this library; see the file COPYING.LIB. If not, write to
  14. the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  15. Boston, MA 02110-1301, USA.
  16. */
  17. #include "config.h"
  18. #include "ewk_history.h"
  19. #include "BackForwardListImpl.h"
  20. #include "CairoUtilitiesEfl.h"
  21. #include "HistoryItem.h"
  22. #include "IconDatabaseBase.h"
  23. #include "Image.h"
  24. #include "IntSize.h"
  25. #include "Page.h"
  26. #include "PageGroup.h"
  27. #include "ewk_history_private.h"
  28. #include "ewk_private.h"
  29. #include <Eina.h>
  30. #include <eina_safety_checks.h>
  31. #include <wtf/text/CString.h>
  32. struct _Ewk_History {
  33. WebCore::BackForwardListImpl* core;
  34. };
  35. #define EWK_HISTORY_CORE_GET_OR_RETURN(history, core_, ...) \
  36. if (!(history)) { \
  37. CRITICAL("history is NULL."); \
  38. return __VA_ARGS__; \
  39. } \
  40. if (!(history)->core) { \
  41. CRITICAL("history->core is NULL."); \
  42. return __VA_ARGS__; \
  43. } \
  44. if (!(history)->core->enabled()) { \
  45. ERR("history->core is disabled!."); \
  46. return __VA_ARGS__; \
  47. } \
  48. WebCore::BackForwardListImpl* core_ = (history)->core
  49. struct _Ewk_History_Item {
  50. WebCore::HistoryItem* core;
  51. const char* title;
  52. const char* alternateTitle;
  53. const char* uri;
  54. const char* originalUri;
  55. };
  56. #define EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core_, ...) \
  57. if (!(item)) { \
  58. CRITICAL("item is NULL."); \
  59. return __VA_ARGS__; \
  60. } \
  61. if (!(item)->core) { \
  62. CRITICAL("item->core is NULL."); \
  63. return __VA_ARGS__; \
  64. } \
  65. WebCore::HistoryItem* core_ = (item)->core
  66. static inline Eina_List* _ewk_history_item_list_get(const WebCore::HistoryItemVector& coreItems)
  67. {
  68. Eina_List* result = 0;
  69. unsigned int size;
  70. size = coreItems.size();
  71. for (unsigned int i = 0; i < size; i++) {
  72. Ewk_History_Item* item = ewk_history_item_new_from_core(coreItems[i].get());
  73. if (item)
  74. result = eina_list_append(result, item);
  75. }
  76. return result;
  77. }
  78. Eina_Bool ewk_history_clear(Ewk_History* history)
  79. {
  80. EWK_HISTORY_CORE_GET_OR_RETURN(history, core, false);
  81. WebCore::Page* page = core->page();
  82. if (page && page->groupPtr())
  83. page->groupPtr()->removeVisitedLinks();
  84. const int limit = ewk_history_limit_get(history);
  85. ewk_history_limit_set(history, 0);
  86. ewk_history_limit_set(history, limit);
  87. return true;
  88. }
  89. Eina_Bool ewk_history_forward(Ewk_History* history)
  90. {
  91. EWK_HISTORY_CORE_GET_OR_RETURN(history, core, false);
  92. if (core->forwardListCount() < 1)
  93. return false;
  94. core->goForward();
  95. return true;
  96. }
  97. Eina_Bool ewk_history_back(Ewk_History* history)
  98. {
  99. EWK_HISTORY_CORE_GET_OR_RETURN(history, core, false);
  100. if (core->backListCount() < 1)
  101. return false;
  102. core->goBack();
  103. return true;
  104. }
  105. Eina_Bool ewk_history_history_item_add(Ewk_History* history, const Ewk_History_Item* item)
  106. {
  107. EWK_HISTORY_CORE_GET_OR_RETURN(history, history_core, false);
  108. EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, item_core, false);
  109. history_core->addItem(item_core);
  110. return true;
  111. }
  112. Eina_Bool ewk_history_history_item_set(Ewk_History* history, const Ewk_History_Item* item)
  113. {
  114. EWK_HISTORY_CORE_GET_OR_RETURN(history, history_core, false);
  115. EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, item_core, false);
  116. history_core->goToItem(item_core);
  117. return true;
  118. }
  119. Ewk_History_Item* ewk_history_history_item_back_get(const Ewk_History* history)
  120. {
  121. EWK_HISTORY_CORE_GET_OR_RETURN(history, core, 0);
  122. return ewk_history_item_new_from_core(core->backItem());
  123. }
  124. Ewk_History_Item* ewk_history_history_item_current_get(const Ewk_History* history)
  125. {
  126. EWK_HISTORY_CORE_GET_OR_RETURN(history, core, 0);
  127. WebCore::HistoryItem* currentItem = core->currentItem();
  128. if (currentItem)
  129. return ewk_history_item_new_from_core(currentItem);
  130. return 0;
  131. }
  132. Ewk_History_Item* ewk_history_history_item_forward_get(const Ewk_History* history)
  133. {
  134. EWK_HISTORY_CORE_GET_OR_RETURN(history, core, 0);
  135. return ewk_history_item_new_from_core(core->forwardItem());
  136. }
  137. Ewk_History_Item* ewk_history_history_item_nth_get(const Ewk_History* history, int index)
  138. {
  139. EWK_HISTORY_CORE_GET_OR_RETURN(history, core, 0);
  140. return ewk_history_item_new_from_core(core->itemAtIndex(index));
  141. }
  142. Eina_Bool ewk_history_history_item_contains(const Ewk_History* history, const Ewk_History_Item* item)
  143. {
  144. EWK_HISTORY_CORE_GET_OR_RETURN(history, history_core, false);
  145. EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, item_core, false);
  146. return history_core->containsItem(item_core);
  147. }
  148. Eina_List* ewk_history_forward_list_get(const Ewk_History* history)
  149. {
  150. EWK_HISTORY_CORE_GET_OR_RETURN(history, core, 0);
  151. WebCore::HistoryItemVector items;
  152. int limit = core->forwardListCount();
  153. core->forwardListWithLimit(limit, items);
  154. return _ewk_history_item_list_get(items);
  155. }
  156. Eina_List* ewk_history_forward_list_get_with_limit(const Ewk_History* history, int limit)
  157. {
  158. EWK_HISTORY_CORE_GET_OR_RETURN(history, core, 0);
  159. WebCore::HistoryItemVector items;
  160. core->forwardListWithLimit(limit, items);
  161. return _ewk_history_item_list_get(items);
  162. }
  163. int ewk_history_forward_list_length(const Ewk_History* history)
  164. {
  165. EWK_HISTORY_CORE_GET_OR_RETURN(history, core, 0);
  166. return core->forwardListCount();
  167. }
  168. Eina_List* ewk_history_back_list_get(const Ewk_History* history)
  169. {
  170. EWK_HISTORY_CORE_GET_OR_RETURN(history, core, 0);
  171. WebCore::HistoryItemVector items;
  172. int limit = core->backListCount();
  173. core->backListWithLimit(limit, items);
  174. return _ewk_history_item_list_get(items);
  175. }
  176. Eina_List* ewk_history_back_list_get_with_limit(const Ewk_History* history, int limit)
  177. {
  178. EWK_HISTORY_CORE_GET_OR_RETURN(history, core, 0);
  179. WebCore::HistoryItemVector items;
  180. core->backListWithLimit(limit, items);
  181. return _ewk_history_item_list_get(items);
  182. }
  183. int ewk_history_back_list_length(const Ewk_History* history)
  184. {
  185. EWK_HISTORY_CORE_GET_OR_RETURN(history, core, 0);
  186. return core->backListCount();
  187. }
  188. int ewk_history_limit_get(Ewk_History* history)
  189. {
  190. EWK_HISTORY_CORE_GET_OR_RETURN(history, core, 0);
  191. return core->capacity();
  192. }
  193. Eina_Bool ewk_history_limit_set(const Ewk_History* history, int limit)
  194. {
  195. EWK_HISTORY_CORE_GET_OR_RETURN(history, core, false);
  196. core->setCapacity(limit);
  197. return true;
  198. }
  199. Ewk_History_Item* ewk_history_item_new_from_core(WebCore::HistoryItem* core)
  200. {
  201. Ewk_History_Item* item;
  202. if (!core) {
  203. ERR("WebCore::HistoryItem is NULL.");
  204. return 0;
  205. }
  206. core->ref();
  207. item = new Ewk_History_Item;
  208. memset(item, 0, sizeof(*item));
  209. item->core = core;
  210. return item;
  211. }
  212. Ewk_History_Item* ewk_history_item_new(const char* uri, const char* title)
  213. {
  214. WTF::String historyUri = WTF::String::fromUTF8(uri);
  215. WTF::String historyTitle = WTF::String::fromUTF8(title);
  216. WTF::RefPtr<WebCore::HistoryItem> core = WebCore::HistoryItem::create(historyUri, historyTitle, 0);
  217. Ewk_History_Item* item = ewk_history_item_new_from_core(core.release().leakRef());
  218. return item;
  219. }
  220. static inline void _ewk_history_item_free(Ewk_History_Item* item, WebCore::HistoryItem* core)
  221. {
  222. core->deref();
  223. delete item;
  224. }
  225. void ewk_history_item_free(Ewk_History_Item* item)
  226. {
  227. EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core);
  228. _ewk_history_item_free(item, core);
  229. }
  230. void ewk_history_item_list_free(Eina_List* history_items)
  231. {
  232. void* deleteItem;
  233. EINA_LIST_FREE(history_items, deleteItem) {
  234. Ewk_History_Item* item = (Ewk_History_Item*)deleteItem;
  235. _ewk_history_item_free(item, item->core);
  236. }
  237. }
  238. const char* ewk_history_item_title_get(const Ewk_History_Item* item)
  239. {
  240. EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core, 0);
  241. // hide the following optimzation from outside
  242. Ewk_History_Item* historyItem = const_cast<Ewk_History_Item*>(item);
  243. eina_stringshare_replace(&historyItem->title, core->title().utf8().data());
  244. return historyItem->title;
  245. }
  246. const char* ewk_history_item_title_alternate_get(const Ewk_History_Item* item)
  247. {
  248. EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core, 0);
  249. // hide the following optimzation from outside
  250. Ewk_History_Item* historyItem = const_cast<Ewk_History_Item*>(item);
  251. eina_stringshare_replace(&historyItem->alternateTitle,
  252. core->alternateTitle().utf8().data());
  253. return historyItem->alternateTitle;
  254. }
  255. void ewk_history_item_title_alternate_set(Ewk_History_Item* item, const char* title)
  256. {
  257. EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core);
  258. if (!eina_stringshare_replace(&item->alternateTitle, title))
  259. return;
  260. core->setAlternateTitle(WTF::String::fromUTF8(title));
  261. }
  262. const char* ewk_history_item_uri_get(const Ewk_History_Item* item)
  263. {
  264. EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core, 0);
  265. // hide the following optimzation from outside
  266. Ewk_History_Item* historyItem = const_cast<Ewk_History_Item*>((item));
  267. eina_stringshare_replace(&historyItem->uri, core->urlString().utf8().data());
  268. return historyItem->uri;
  269. }
  270. const char* ewk_history_item_uri_original_get(const Ewk_History_Item* item)
  271. {
  272. EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core, 0);
  273. // hide the following optimzation from outside
  274. Ewk_History_Item* historyItem = const_cast<Ewk_History_Item*>(item);
  275. eina_stringshare_replace(&historyItem->originalUri,
  276. core->originalURLString().utf8().data());
  277. return historyItem->originalUri;
  278. }
  279. double ewk_history_item_time_last_visited_get(const Ewk_History_Item* item)
  280. {
  281. EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core, 0.0);
  282. return core->lastVisitedTime();
  283. }
  284. cairo_surface_t* ewk_history_item_icon_surface_get(const Ewk_History_Item* item)
  285. {
  286. EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core, 0);
  287. RefPtr<cairo_surface_t> icon = WebCore::iconDatabase().synchronousNativeIconForPageURL(core->url(), WebCore::IntSize(16, 16));
  288. if (!icon)
  289. ERR("icon is NULL.");
  290. return icon.get();
  291. }
  292. Evas_Object* ewk_history_item_icon_object_add(const Ewk_History_Item* item, Evas* canvas)
  293. {
  294. EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core, 0);
  295. EINA_SAFETY_ON_NULL_RETURN_VAL(canvas, 0);
  296. RefPtr<cairo_surface_t> surface = WebCore::iconDatabase().synchronousNativeIconForPageURL(core->url(), WebCore::IntSize(16, 16));
  297. if (!surface) {
  298. ERR("icon is NULL.");
  299. return 0;
  300. }
  301. return surface ? WebCore::evasObjectFromCairoImageSurface(canvas, surface.get()).leakRef() : 0;
  302. }
  303. Eina_Bool ewk_history_item_page_cache_exists(const Ewk_History_Item* item)
  304. {
  305. EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core, false);
  306. return core->isInPageCache();
  307. }
  308. int ewk_history_item_visit_count(const Ewk_History_Item* item)
  309. {
  310. EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core, 0);
  311. return core->visitCount();
  312. }
  313. Eina_Bool ewk_history_item_visit_last_failed(const Ewk_History_Item* item)
  314. {
  315. EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core, true);
  316. return core->lastVisitWasFailure();
  317. }
  318. /* internal methods ****************************************************/
  319. /**
  320. * @internal
  321. *
  322. * Creates history for given view. Called internally by ewk_view and
  323. * should never be called from outside.
  324. *
  325. * @param core WebCore::BackForwardListImpl instance to use internally.
  326. *
  327. * @return newly allocated history instance or @c NULL on errors.
  328. */
  329. Ewk_History* ewk_history_new(WebCore::BackForwardListImpl* core)
  330. {
  331. Ewk_History* history;
  332. EINA_SAFETY_ON_NULL_RETURN_VAL(core, 0);
  333. DBG("core=%p", core);
  334. history = new Ewk_History;
  335. history->core = core;
  336. core->ref();
  337. return history;
  338. }
  339. /**
  340. * @internal
  341. *
  342. * Destroys previously allocated history instance. This is called
  343. * automatically by ewk_view and should never be called from outside.
  344. *
  345. * @param history instance to free
  346. */
  347. void ewk_history_free(Ewk_History* history)
  348. {
  349. DBG("history=%p", history);
  350. history->core->deref();
  351. delete history;
  352. }
  353. namespace EWKPrivate {
  354. WebCore::HistoryItem* coreHistoryItem(const Ewk_History_Item* ewkHistoryItem)
  355. {
  356. EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(ewkHistoryItem, core, 0);
  357. return core;
  358. }
  359. } // namespace EWKPrivate