2 Copyright (C) 2009-2010 ProFUSION embedded systems
3 Copyright (C) 2009-2010 Samsung Electronics
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
22 #include "ewk_history.h"
24 #include "BackForwardListImpl.h"
26 #include "HistoryItem.h"
27 #include "IconDatabaseBase.h"
30 #include "ewk_private.h"
33 #include <eina_safety_checks.h>
34 #include <wtf/text/CString.h>
37 WebCore::BackForwardListImpl *core;
40 #define EWK_HISTORY_CORE_GET_OR_RETURN(history, core_, ...) \
42 CRITICAL("history is NULL."); \
45 if (!(history)->core) { \
46 CRITICAL("history->core is NULL."); \
49 if (!(history)->core->enabled()) { \
50 ERR("history->core is disabled!."); \
53 WebCore::BackForwardListImpl *core_ = (history)->core
56 struct _Ewk_History_Item {
57 WebCore::HistoryItem *core;
60 const char *alternate_title;
62 const char *original_uri;
65 #define EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core_, ...) \
67 CRITICAL("item is NULL."); \
70 if (!(item)->core) { \
71 CRITICAL("item->core is NULL."); \
74 WebCore::HistoryItem *core_ = (item)->core
77 static inline Ewk_History_Item *_ewk_history_item_new(WebCore::HistoryItem *core)
79 Ewk_History_Item* item;
82 ERR("WebCore::HistoryItem is NULL.");
86 item = (Ewk_History_Item *)calloc(1, sizeof(Ewk_History_Item));
88 CRITICAL("Could not allocate item memory.");
98 static inline Eina_List *_ewk_history_item_list_get(const WebCore::HistoryItemVector &core_items)
101 unsigned int i, size;
103 size = core_items.size();
104 for (i = 0; i < size; i++) {
105 Ewk_History_Item* item = _ewk_history_item_new(core_items[i].get());
107 ret = eina_list_append(ret, item);
113 Eina_Bool ewk_history_forward(Ewk_History* history)
115 EWK_HISTORY_CORE_GET_OR_RETURN(history, core, EINA_FALSE);
116 if (core->forwardListCount() < 1)
122 Eina_Bool ewk_history_back(Ewk_History* history)
124 EWK_HISTORY_CORE_GET_OR_RETURN(history, core, EINA_FALSE);
125 if (core->backListCount() < 1)
131 Eina_Bool ewk_history_history_item_add(Ewk_History* history, const Ewk_History_Item* item)
133 EWK_HISTORY_CORE_GET_OR_RETURN(history, history_core, EINA_FALSE);
134 EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, item_core, EINA_FALSE);
135 history_core->addItem(item_core);
139 Eina_Bool ewk_history_history_item_set(Ewk_History* history, const Ewk_History_Item* item)
141 EWK_HISTORY_CORE_GET_OR_RETURN(history, history_core, EINA_FALSE);
142 EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, item_core, EINA_FALSE);
143 history_core->goToItem(item_core);
147 Ewk_History_Item* ewk_history_history_item_back_get(const Ewk_History* history)
149 EWK_HISTORY_CORE_GET_OR_RETURN(history, core, 0);
150 return _ewk_history_item_new(core->backItem());
153 Ewk_History_Item* ewk_history_history_item_current_get(const Ewk_History* history)
155 EWK_HISTORY_CORE_GET_OR_RETURN(history, core, 0);
156 WebCore::HistoryItem *currentItem = core->currentItem();
158 return _ewk_history_item_new(currentItem);
162 Ewk_History_Item* ewk_history_history_item_forward_get(const Ewk_History* history)
164 EWK_HISTORY_CORE_GET_OR_RETURN(history, core, 0);
165 return _ewk_history_item_new(core->forwardItem());
168 Ewk_History_Item* ewk_history_history_item_nth_get(const Ewk_History* history, int index)
170 EWK_HISTORY_CORE_GET_OR_RETURN(history, core, 0);
171 return _ewk_history_item_new(core->itemAtIndex(index));
174 Eina_Bool ewk_history_history_item_contains(const Ewk_History* history, const Ewk_History_Item* item)
176 EWK_HISTORY_CORE_GET_OR_RETURN(history, history_core, EINA_FALSE);
177 EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, item_core, EINA_FALSE);
178 return history_core->containsItem(item_core);
181 Eina_List* ewk_history_forward_list_get(const Ewk_History* history)
183 EWK_HISTORY_CORE_GET_OR_RETURN(history, core, 0);
184 WebCore::HistoryItemVector items;
185 int limit = core->forwardListCount();
186 core->forwardListWithLimit(limit, items);
187 return _ewk_history_item_list_get(items);
190 Eina_List* ewk_history_forward_list_get_with_limit(const Ewk_History* history, int limit)
192 EWK_HISTORY_CORE_GET_OR_RETURN(history, core, 0);
193 WebCore::HistoryItemVector items;
194 core->forwardListWithLimit(limit, items);
195 return _ewk_history_item_list_get(items);
198 int ewk_history_forward_list_length(const Ewk_History* history)
200 EWK_HISTORY_CORE_GET_OR_RETURN(history, core, 0);
201 return core->forwardListCount();
204 Eina_List* ewk_history_back_list_get(const Ewk_History* history)
206 EWK_HISTORY_CORE_GET_OR_RETURN(history, core, 0);
207 WebCore::HistoryItemVector items;
208 int limit = core->backListCount();
209 core->backListWithLimit(limit, items);
210 return _ewk_history_item_list_get(items);
213 Eina_List* ewk_history_back_list_get_with_limit(const Ewk_History* history, int limit)
215 EWK_HISTORY_CORE_GET_OR_RETURN(history, core, 0);
216 WebCore::HistoryItemVector items;
217 core->backListWithLimit(limit, items);
218 return _ewk_history_item_list_get(items);
221 int ewk_history_back_list_length(const Ewk_History* history)
223 EWK_HISTORY_CORE_GET_OR_RETURN(history, core, 0);
224 return core->backListCount();
227 int ewk_history_limit_get(Ewk_History* history)
229 EWK_HISTORY_CORE_GET_OR_RETURN(history, core, 0);
230 return core->capacity();
233 Eina_Bool ewk_history_limit_set(const Ewk_History* history, int limit)
235 EWK_HISTORY_CORE_GET_OR_RETURN(history, core, EINA_FALSE);
236 core->setCapacity(limit);
240 Ewk_History_Item* ewk_history_item_new(const char* uri, const char* title)
242 WTF::String u = WTF::String::fromUTF8(uri);
243 WTF::String t = WTF::String::fromUTF8(title);
244 WTF::RefPtr<WebCore::HistoryItem> core = WebCore::HistoryItem::create(u, t, 0);
245 Ewk_History_Item* item = _ewk_history_item_new(core.release().releaseRef());
249 static inline void _ewk_history_item_free(Ewk_History_Item* item, WebCore::HistoryItem* core)
255 void ewk_history_item_free(Ewk_History_Item* item)
257 EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core);
258 _ewk_history_item_free(item, core);
261 void ewk_history_item_list_free(Eina_List* history_items)
264 EINA_LIST_FREE(history_items, d) {
265 Ewk_History_Item* item = (Ewk_History_Item*)d;
266 _ewk_history_item_free(item, item->core);
270 const char* ewk_history_item_title_get(const Ewk_History_Item* item)
272 EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core, 0);
273 // hide the following optimzation from outside
274 Ewk_History_Item* i = (Ewk_History_Item*)item;
275 eina_stringshare_replace(&i->title, core->title().utf8().data());
279 const char* ewk_history_item_title_alternate_get(const Ewk_History_Item* item)
281 EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core, 0);
282 // hide the following optimzation from outside
283 Ewk_History_Item* i = (Ewk_History_Item*)item;
284 eina_stringshare_replace(&i->alternate_title,
285 core->alternateTitle().utf8().data());
286 return i->alternate_title;
289 void ewk_history_item_title_alternate_set(Ewk_History_Item* item, const char* title)
291 EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core);
292 if (!eina_stringshare_replace(&item->alternate_title, title))
294 core->setAlternateTitle(WTF::String::fromUTF8(title));
297 const char* ewk_history_item_uri_get(const Ewk_History_Item* item)
299 EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core, 0);
300 // hide the following optimzation from outside
301 Ewk_History_Item* i = (Ewk_History_Item*)item;
302 eina_stringshare_replace(&i->uri, core->urlString().utf8().data());
306 const char* ewk_history_item_uri_original_get(const Ewk_History_Item* item)
308 EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core, 0);
309 // hide the following optimzation from outside
310 Ewk_History_Item* i = (Ewk_History_Item*)item;
311 eina_stringshare_replace(&i->original_uri,
312 core->originalURLString().utf8().data());
313 return i->original_uri;
316 double ewk_history_item_time_last_visited_get(const Ewk_History_Item* item)
318 EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core, 0.0);
319 return core->lastVisitedTime();
322 cairo_surface_t* ewk_history_item_icon_surface_get(const Ewk_History_Item* item)
324 EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core, 0);
326 WebCore::Image* icon = WebCore::iconDatabase().synchronousIconForPageURL(core->url(), WebCore::IntSize(16, 16));
328 ERR("icon is NULL.");
331 return icon->nativeImageForCurrentFrame();
334 Evas_Object* ewk_history_item_icon_object_add(const Ewk_History_Item* item, Evas* canvas)
336 EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core, 0);
337 EINA_SAFETY_ON_NULL_RETURN_VAL(canvas, 0);
338 WebCore::Image* icon = WebCore::iconDatabase().synchronousIconForPageURL(core->url(), WebCore::IntSize(16, 16));
339 cairo_surface_t* surface;
342 ERR("icon is NULL.");
346 surface = icon->nativeImageForCurrentFrame();
347 return ewk_util_image_from_cairo_surface_add(canvas, surface);
350 Eina_Bool ewk_history_item_page_cache_exists(const Ewk_History_Item* item)
352 EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core, EINA_FALSE);
353 return core->isInPageCache();
356 int ewk_history_item_visit_count(const Ewk_History_Item* item)
358 EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core, 0);
359 return core->visitCount();
362 Eina_Bool ewk_history_item_visit_last_failed(const Ewk_History_Item* item)
364 EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core, EINA_TRUE);
365 return core->lastVisitWasFailure();
369 /* internal methods ****************************************************/
373 * Creates history for given view. Called internally by ewk_view and
374 * should never be called from outside.
376 * @param core WebCore::BackForwardListImpl instance to use internally.
378 * @return newly allocated history instance or @c NULL on errors.
380 Ewk_History* ewk_history_new(WebCore::BackForwardListImpl* core)
382 Ewk_History* history;
383 EINA_SAFETY_ON_NULL_RETURN_VAL(core, 0);
384 DBG("core=%p", core);
386 history = (Ewk_History*)malloc(sizeof(Ewk_History));
388 CRITICAL("Could not allocate history memory.");
393 history->core = core;
401 * Destroys previously allocated history instance. This is called
402 * automatically by ewk_view and should never be called from outside.
404 * @param history instance to free
406 void ewk_history_free(Ewk_History* history)
408 DBG("history=%p", history);
409 history->core->deref();
416 * Returns a newly-allocated string with the item's target name.
417 * Callers are responsible for freeing the allocated memory with free(3).
419 * @param item instance to operate upon.
421 char* ewk_history_item_target_get(const Ewk_History_Item* item)
423 EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core, 0);
424 return strdup(core->target().utf8().data());
430 * Returns whether the given item is currently a target.
432 * @param item instance to check.
434 Eina_Bool ewk_history_item_target_is(const Ewk_History_Item* item)
436 EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core, 0);
437 return core->isTargetItem();
443 * Returns a list of child history items relative to the given item,
444 * or @c NULL if there are none.
446 * @param item instance to operate upon.
448 Eina_List* ewk_history_item_children_get(const Ewk_History_Item* item)
450 EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core, 0);
451 const WebCore::HistoryItemVector& children = core->children();
452 if (!children.size())
456 const unsigned size = children.size();
457 for (unsigned i = 0; i < size; ++i)
458 kids = eina_list_append(kids, _ewk_history_item_new(children[i].get()));