static void write_children_recursive(WTF::Vector<char>& v, WebCore::HistoryItem* parent) { const WebCore::HistoryItemVector& children = parent->children(); WebCore::HistoryItemVector::const_iterator end = children.end(); for (WebCore::HistoryItemVector::const_iterator i = children.begin(); i != end; ++i) { WebCore::HistoryItem* item = (*i).get(); LOG_ASSERT(parent->bridge(), "The parent item should have a bridge object!"); if (!item->bridge()) { WebHistoryItem* bridge = new WebHistoryItem(static_cast<WebHistoryItem*>(parent->bridge())); item->setBridge(bridge); bridge->setActive(); } else { // The only time this item's parent may not be the same as the // parent's bridge is during history close. In that case, the // parent must not have a parent bridge. WebHistoryItem* bridge = static_cast<WebHistoryItem*>(item->bridge()); WebHistoryItem* parentBridge = static_cast<WebHistoryItem*>(parent->bridge()); LOG_ASSERT(parentBridge->parent() == 0 || bridge->parent() == parentBridge, "Somehow this item has an incorrect parent"); bridge->setParent(parentBridge); } write_item(v, item); write_children_recursive(v, item); } }
void WebHistoryItem::updateHistoryItem(WebCore::HistoryItem* item) { // Do not want to update during inflation. if (!m_active) return; WebHistoryItem* webItem = this; // Now we need to update the top-most WebHistoryItem based on the top-most // HistoryItem. if (m_parent) { webItem = m_parent.get(); if (webItem->hasOneRef()) { // if the parent only has one ref, it is from this WebHistoryItem. // This means that the matching WebCore::HistoryItem has been freed. // This can happen during clear(). LOGW("Can't updateHistoryItem as the top HistoryItem is gone"); return; } while (webItem->parent()) webItem = webItem->parent(); item = webItem->historyItem(); if (!item) { // If a HistoryItem only exists for page cache, it is possible that // the parent HistoryItem destroyed before the child HistoryItem. If // it happens, skip updating. LOGW("Can't updateHistoryItem as the top HistoryItem is gone"); return; } } JNIEnv* env = JSC::Bindings::getJNIEnv(); if (!env) return; // Don't do anything if the item has been gc'd already AutoJObject realItem = getRealObject(env, webItem->m_object); if (!realItem.get()) return; const WebCore::String& urlString = item->urlString(); jstring urlStr = NULL; if (!urlString.isNull()) urlStr = env->NewString((unsigned short*)urlString.characters(), urlString.length()); const WebCore::String& originalUrlString = item->originalURLString(); jstring originalUrlStr = NULL; if (!originalUrlString.isNull()) { originalUrlStr = env->NewString( (unsigned short*) originalUrlString.characters(), originalUrlString.length()); } const WebCore::String& titleString = item->title(); jstring titleStr = NULL; if (!titleString.isNull()) titleStr = env->NewString((unsigned short*)titleString.characters(), titleString.length()); // Try to get the favicon from the history item. For some pages like Grand // Prix, there are history items with anchors. If the icon fails for the // item, try to get the icon using the url without the ref. jobject favicon = NULL; WebCore::String url = item->urlString(); if (item->url().hasFragmentIdentifier()) { int refIndex = url.reverseFind('#'); url = url.substring(0, refIndex); } WebCore::Image* icon = WebCore::iconDatabase()->iconForPageURL(url, WebCore::IntSize(16, 16)); if (icon) favicon = webcoreImageToJavaBitmap(env, icon); WTF::Vector<char> data; jbyteArray array = WebHistory::Flatten(env, data, item); env->CallVoidMethod(realItem.get(), gWebHistoryItem.mUpdate, urlStr, originalUrlStr, titleStr, favicon, array); env->DeleteLocalRef(urlStr); env->DeleteLocalRef(originalUrlStr); env->DeleteLocalRef(titleStr); if (favicon) env->DeleteLocalRef(favicon); env->DeleteLocalRef(array); }
void WebHistoryItem::updateHistoryItem(WebCore::HistoryItem* item) { // Do not want to update during inflation. if (!m_active) return; WebHistoryItem* webItem = this; // Now we need to update the top-most WebHistoryItem based on the top-most // HistoryItem. if (m_parent) { webItem = m_parent.get(); if (webItem->hasOneRef()) { // if the parent only has one ref, it is from this WebHistoryItem. // This means that the matching WebCore::HistoryItem has been freed. // This can happen during clear(). ALOGW("Can't updateHistoryItem as the top HistoryItem is gone"); return; } while (webItem->parent()) webItem = webItem->parent(); item = webItem->historyItem(); if (!item) { // If a HistoryItem only exists for page cache, it is possible that // the parent HistoryItem destroyed before the child HistoryItem. If // it happens, skip updating. ALOGW("Can't updateHistoryItem as the top HistoryItem is gone"); return; } } JNIEnv* env = JSC::Bindings::getJNIEnv(); if (!env) return; MutexLocker locker(webItem->m_lock); // TODO: Figure out if we can't just use item->urlString() instead... const WTF::String urlString = WebFrame::convertIDNToUnicode(item->url()); webItem->m_url = urlString.threadsafeCopy(); const WTF::String originalUrlString = WebFrame::convertIDNToUnicode(item->originalURL()); webItem->m_originalUrl = originalUrlString.threadsafeCopy(); const WTF::String& titleString = item->title(); webItem->m_title = titleString.threadsafeCopy(); // Try to get the favicon from the history item. For some pages like Grand // Prix, there are history items with anchors. If the icon fails for the // item, try to get the icon using the url without the ref. jobject favicon = NULL; WTF::String url = item->urlString(); if (item->url().hasFragmentIdentifier()) { int refIndex = url.reverseFind('#'); url = url.substring(0, refIndex); } // FIXME: This method should not be used from outside WebCore and will be removed. // http://trac.webkit.org/changeset/81484 WebCore::Image* icon = WebCore::iconDatabase().synchronousIconForPageURL(url, WebCore::IntSize(16, 16)); delete webItem->m_favicon; webItem->m_favicon = webcoreImageToSkBitmap(icon); if (webItem->m_faviconCached) { env->DeleteGlobalRef(webItem->m_faviconCached); webItem->m_faviconCached = 0; } webItem->m_data.clear(); WebHistory::Flatten(env, webItem->m_data, item); if (webItem->m_dataCached) { env->DeleteGlobalRef(webItem->m_dataCached); webItem->m_dataCached = 0; } }