// entry.getChildren() JNIEXPORT jobjectArray JNICALL Java_com_sun_webkit_BackForwardList_bflItemGetChildren(JNIEnv* env, jclass z, jlong jitem, jlong jpage) { HistoryItem* item = getItem(jitem); if (!item->hasChildren()) { return NULL; } jobjectArray children = env->NewObjectArray(item->children().size(), getJEntryClass(), NULL); int i = 0; for (HistoryItemVector::const_iterator it = item->children().begin(); it != item->children().end(); ++it) { env->SetObjectArrayElement(children, i++, (jobject)createEntry(&**it, jpage)); } return children; }
QMap<QString, QWebHistoryItem> DumpRenderTreeSupportQt::getChildHistoryItems(const QWebHistoryItem& historyItem) { QWebHistoryItem it = historyItem; HistoryItem* item = QWebHistoryItemPrivate::core(&it); const WebCore::HistoryItemVector& children = item->children(); unsigned size = children.size(); QMap<QString, QWebHistoryItem> kids; for (unsigned i = 0; i < size; ++i) { QWebHistoryItem kid(new QWebHistoryItemPrivate(children[i].get())); kids.insert(DumpRenderTreeSupportQt::historyItemTarget(kid), kid); } return kids; }
// Does a non-recursive check that this item and its immediate children have the // same frames as the other item. bool HistoryItem::hasSameFrames(HistoryItem& otherItem) const { if (target() != otherItem.target()) return false; if (children().size() != otherItem.children().size()) return false; for (size_t i = 0; i < children().size(); i++) { if (!otherItem.childItemWithTarget(children()[i]->target())) return false; } return true; }
// We now traverse the frame tree and item tree a second time, loading frames that // do have the content the item requests. void HistoryController::recursiveGoToItem(HistoryItem& item, HistoryItem* fromItem, FrameLoadType type) { if (!itemsAreClones(item, fromItem)) { m_frame.loader().loadItem(item, type); return; } // Just iterate over the rest, looking for frames to navigate. for (auto& childItem : item.children()) { const String& childFrameName = childItem->target(); HistoryItem* fromChildItem = fromItem->childItemWithTarget(childFrameName); ASSERT(fromChildItem); if (Frame* childFrame = m_frame.tree().child(childFrameName)) childFrame->loader().history().recursiveGoToItem(const_cast<HistoryItem&>(childItem.get()), fromChildItem, type); } }
// Does a recursive check that this item and its descendants have the same // document sequence numbers as the other item. bool HistoryItem::hasSameDocumentTree(HistoryItem& otherItem) const { if (documentSequenceNumber() != otherItem.documentSequenceNumber()) return false; if (children().size() != otherItem.children().size()) return false; for (size_t i = 0; i < children().size(); i++) { auto& child = children()[i].get(); auto* otherChild = otherItem.childItemWithDocumentSequenceNumber(child.documentSequenceNumber()); if (!otherChild || !child.hasSameDocumentTree(*otherChild)) return false; } return true; }
void WebFrameLoaderClient::loadURLIntoChild(const KURL& originalURL, const String& referrer, WebFrame* childFrame) { ASSERT(childFrame); ASSERT(core(childFrame)); Frame* coreFrame = core(m_webFrame); ASSERT(coreFrame); HistoryItem* parentItem = coreFrame->loader()->currentHistoryItem(); FrameLoadType loadType = coreFrame->loader()->loadType(); FrameLoadType childLoadType = FrameLoadTypeRedirectWithLockedHistory; KURL url = originalURL; // If we're moving in the backforward list, we might want to replace the content // of this child frame with whatever was there at that point. // Reload will maintain the frame contents, LoadSame will not. if (parentItem && parentItem->children().size() && (isBackForwardLoadType(loadType) || loadType == FrameLoadTypeReload || loadType == FrameLoadTypeReloadAllowingStaleData)) { if (HistoryItem* childItem = parentItem->childItemWithName(core(childFrame)->tree()->name())) { // Use the original URL to ensure we get all the side-effects, such as // onLoad handlers, of any redirects that happened. An example of where // this is needed is Radar 3213556. url = childItem->originalURL(); // These behaviors implied by these loadTypes should apply to the child frames childLoadType = loadType; if (isBackForwardLoadType(loadType)) // For back/forward, remember this item so we can traverse any child items as child frames load core(childFrame)->loader()->setProvisionalHistoryItem(childItem); else // For reload, just reinstall the current item, since a new child frame was created but we won't be creating a new BF item core(childFrame)->loader()->setCurrentHistoryItem(childItem); } } // FIXME: Handle loading WebArchives here String frameName = core(childFrame)->tree()->name(); core(childFrame)->loader()->loadURL(url, referrer, frameName, childLoadType, 0, 0); }
// The general idea here is to traverse the frame tree and the item tree in parallel, // tracking whether each frame already has the content the item requests. If there is // a match, we set the provisional item and recurse. Otherwise we will reload that // frame and all its kids in recursiveGoToItem. void HistoryController::recursiveSetProvisionalItem(HistoryItem& item, HistoryItem* fromItem) { if (!itemsAreClones(item, fromItem)) return; // Set provisional item, which will be committed in recursiveUpdateForCommit. m_provisionalItem = &item; for (auto& childItem : item.children()) { const String& childFrameName = childItem->target(); HistoryItem* fromChildItem = fromItem->childItemWithTarget(childFrameName); ASSERT(fromChildItem); Frame* childFrame = m_frame.tree().child(childFrameName); ASSERT(childFrame); childFrame->loader().history().recursiveSetProvisionalItem(const_cast<HistoryItem&>(childItem.get()), fromChildItem); } }
static FrameState toFrameState(const HistoryItem& historyItem) { FrameState frameState; frameState.urlString = historyItem.urlString(); frameState.originalURLString = historyItem.originalURLString(); frameState.referrer = historyItem.referrer(); frameState.target = historyItem.target(); frameState.documentState = historyItem.documentState(); if (RefPtr<SerializedScriptValue> stateObject = historyItem.stateObject()) frameState.stateObjectData = stateObject->data(); frameState.documentSequenceNumber = historyItem.documentSequenceNumber(); frameState.itemSequenceNumber = historyItem.itemSequenceNumber(); frameState.scrollPoint = historyItem.scrollPoint(); frameState.pageScaleFactor = historyItem.pageScaleFactor(); if (FormData* formData = const_cast<HistoryItem&>(historyItem).formData()) { HTTPBody httpBody = toHTTPBody(*formData); httpBody.contentType = historyItem.formContentType(); frameState.httpBody = WTF::move(httpBody); } #if PLATFORM(IOS) frameState.exposedContentRect = historyItem.exposedContentRect(); frameState.unobscuredContentRect = historyItem.unobscuredContentRect(); frameState.minimumLayoutSizeInScrollViewCoordinates = historyItem.minimumLayoutSizeInScrollViewCoordinates(); frameState.contentSize = historyItem.contentSize(); frameState.scaleIsInitial = historyItem.scaleIsInitial(); #endif for (auto& childHistoryItem : historyItem.children()) { FrameState childFrameState = toFrameState(childHistoryItem); frameState.children.append(WTF::move(childFrameState)); } return frameState; }