/*! Clears the history. \sa count(), items() */ void QWebHistory::clear() { //shortcut to private BackForwardListImpl WebCore::BackForwardListImpl* lst = d->lst; //clear visited links WebCore::Page* page = static_cast<WebCore::BackForwardListImpl*>(lst)->page(); if (page && page->groupPtr()) page->groupPtr()->removeVisitedLinks(); //if count() == 0 then just return if (!lst->entries().size()) return; RefPtr<WebCore::HistoryItem> current = lst->currentItem(); int capacity = lst->capacity(); lst->setCapacity(0); lst->setCapacity(capacity); //revert capacity lst->addItem(current.get()); //insert old current item lst->goToItem(current.get()); //and set it as current again d->page()->updateNavigationActions(); }
static void WebHistoryClose(JNIEnv* env, jobject obj, jint frame) { ALOG_ASSERT(frame, "Close needs a valid Frame pointer!"); WebCore::Frame* pFrame = (WebCore::Frame*)frame; WebCore::BackForwardListImpl* list = static_cast<WebCore::BackForwardListImpl*>(pFrame->page()->backForwardList()); RefPtr<WebCore::HistoryItem> current = list->currentItem(); // Remove each item instead of using close(). close() is intended to be used // right before the list is deleted. WebCore::HistoryItemVector& entries = list->entries(); int size = entries.size(); for (int i = size - 1; i >= 0; --i) list->removeItem(entries[i].get()); // Add the current item back to the list. if (current) { current->setBridge(0); // addItem will update the children to match the newly created bridge list->addItem(current); /* * The Grand Prix site uses anchor navigations to change the display. * WebKit tries to be smart and not load child frames that have the * same history urls during an anchor navigation. This means that the * current history item stored in the child frame's loader does not * match the item found in the history tree. If we remove all the * entries in the back/foward list, we have to restore the entire tree * or else a HistoryItem might have a deleted parent. * * In order to restore the history tree correctly, we have to look up * all the frames first and then look up the history item. We do this * because the history item in the tree may be null at this point. * Unfortunately, a HistoryItem can only search its immediately * children so we do a breadth-first rebuild of the tree. */ // Keep a small list of child frames to traverse. WTF::Vector<WebCore::Frame*> frameQueue; // Fix the top-level item. pFrame->loader()->history()->setCurrentItem(current.get()); WebCore::Frame* child = pFrame->tree()->firstChild(); // Remember the parent history item so we can search for a child item. RefPtr<WebCore::HistoryItem> parent = current; while (child) { // Use the old history item since the current one may have a // deleted parent. WebCore::HistoryItem* item = parent->childItemWithTarget(child->tree()->name()); child->loader()->history()->setCurrentItem(item); // Append the first child to the queue if it exists. If there is no // item, then we do not need to traverse the children since there // will be no parent history item. WebCore::Frame* firstChild; if (item && (firstChild = child->tree()->firstChild())) frameQueue.append(firstChild); child = child->tree()->nextSibling(); // If we don't have a sibling for this frame and the queue isn't // empty, use the next entry in the queue. if (!child && !frameQueue.isEmpty()) { child = frameQueue.at(0); frameQueue.remove(0); // Figure out the parent history item used when searching for // the history item to use. parent = child->tree()->parent()->loader()->history()->currentItem(); } } } }