diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/history/HistoryItem.cpp | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/WebCore/history/HistoryItem.cpp')
-rw-r--r-- | Source/WebCore/history/HistoryItem.cpp | 474 |
1 files changed, 70 insertions, 404 deletions
diff --git a/Source/WebCore/history/HistoryItem.cpp b/Source/WebCore/history/HistoryItem.cpp index 8ce0841b9..7a5fbbb45 100644 --- a/Source/WebCore/history/HistoryItem.cpp +++ b/Source/WebCore/history/HistoryItem.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005, 2006, 2008, 2011 Apple Inc. All rights reserved. + * Copyright (C) 2005, 2006, 2008, 2011, 2014 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -10,10 +10,10 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR @@ -37,14 +37,10 @@ #include <stdio.h> #include <wtf/CurrentTime.h> #include <wtf/DateMath.h> -#include <wtf/Decoder.h> -#include <wtf/Encoder.h> #include <wtf/text/CString.h> namespace WebCore { -const uint32_t backForwardTreeEncodingVersion = 2; - static long long generateSequenceNumber() { // Initialize to the current time to reduce the likelihood of generating @@ -57,7 +53,7 @@ static void defaultNotifyHistoryItemChanged(HistoryItem*) { } -void (*notifyHistoryItemChanged)(HistoryItem*) = defaultNotifyHistoryItemChanged; +WEBCORE_EXPORT void (*notifyHistoryItemChanged)(HistoryItem*) = defaultNotifyHistoryItemChanged; HistoryItem::HistoryItem() : m_pageScaleFactor(0) @@ -65,13 +61,7 @@ HistoryItem::HistoryItem() , m_isTargetItem(false) , m_itemSequenceNumber(generateSequenceNumber()) , m_documentSequenceNumber(generateSequenceNumber()) - , m_next(0) - , m_prev(0) -#if PLATFORM(IOS) - , m_scale(0) - , m_scaleIsInitial(false) - , m_bookmarkID(0) -#endif + , m_pruningReason(PruningReason::None) { } @@ -84,14 +74,8 @@ HistoryItem::HistoryItem(const String& urlString, const String& title) , m_isTargetItem(false) , m_itemSequenceNumber(generateSequenceNumber()) , m_documentSequenceNumber(generateSequenceNumber()) - , m_next(0) - , m_prev(0) -#if PLATFORM(IOS) - , m_scale(0) - , m_scaleIsInitial(false) - , m_bookmarkID(0) -#endif -{ + , m_pruningReason(PruningReason::None) +{ iconDatabase().retainIconForPageURL(m_urlString); } @@ -105,39 +89,11 @@ HistoryItem::HistoryItem(const String& urlString, const String& title, const Str , m_isTargetItem(false) , m_itemSequenceNumber(generateSequenceNumber()) , m_documentSequenceNumber(generateSequenceNumber()) - , m_next(0) - , m_prev(0) -#if PLATFORM(IOS) - , m_scale(0) - , m_scaleIsInitial(false) - , m_bookmarkID(0) -#endif + , m_pruningReason(PruningReason::None) { iconDatabase().retainIconForPageURL(m_urlString); } -HistoryItem::HistoryItem(const URL& url, const String& target, const String& parent, const String& title) - : m_urlString(url.string()) - , m_originalURLString(url.string()) - , m_target(target) - , m_parent(parent) - , m_title(title) - , m_pageScaleFactor(0) - , m_lastVisitWasFailure(false) - , m_isTargetItem(false) - , m_itemSequenceNumber(generateSequenceNumber()) - , m_documentSequenceNumber(generateSequenceNumber()) - , m_next(0) - , m_prev(0) -#if PLATFORM(IOS) - , m_scale(0) - , m_scaleIsInitial(false) - , m_bookmarkID(0) -#endif -{ - iconDatabase().retainIconForPageURL(m_urlString); -} - HistoryItem::~HistoryItem() { ASSERT(!m_cachedPage); @@ -150,21 +106,20 @@ inline HistoryItem::HistoryItem(const HistoryItem& item) , m_originalURLString(item.m_originalURLString) , m_referrer(item.m_referrer) , m_target(item.m_target) - , m_parent(item.m_parent) , m_title(item.m_title) , m_displayTitle(item.m_displayTitle) - , m_scrollPoint(item.m_scrollPoint) + , m_scrollPosition(item.m_scrollPosition) , m_pageScaleFactor(item.m_pageScaleFactor) , m_lastVisitWasFailure(item.m_lastVisitWasFailure) , m_isTargetItem(item.m_isTargetItem) , m_itemSequenceNumber(item.m_itemSequenceNumber) , m_documentSequenceNumber(item.m_documentSequenceNumber) , m_formContentType(item.m_formContentType) + , m_pruningReason(PruningReason::None) #if PLATFORM(IOS) + , m_obscuredInset(item.m_obscuredInset) , m_scale(item.m_scale) , m_scaleIsInitial(item.m_scaleIsInitial) - , m_bookmarkID(item.m_bookmarkID) - , m_sharedLinkUniqueIdentifier(item.m_sharedLinkUniqueIdentifier) #endif { if (item.m_formData) @@ -174,14 +129,11 @@ inline HistoryItem::HistoryItem(const HistoryItem& item) m_children.reserveInitialCapacity(size); for (unsigned i = 0; i < size; ++i) m_children.uncheckedAppend(item.m_children[i]->copy()); - - if (item.m_redirectURLs) - m_redirectURLs = std::make_unique<Vector<String>>(*item.m_redirectURLs); } -PassRefPtr<HistoryItem> HistoryItem::copy() const +Ref<HistoryItem> HistoryItem::copy() const { - return adoptRef(new HistoryItem(*this)); + return adoptRef(*new HistoryItem(*this)); } void HistoryItem::reset() @@ -192,21 +144,18 @@ void HistoryItem::reset() m_originalURLString = String(); m_referrer = String(); m_target = String(); - m_parent = String(); m_title = String(); m_displayTitle = String(); m_lastVisitWasFailure = false; m_isTargetItem = false; - m_redirectURLs = nullptr; - m_itemSequenceNumber = generateSequenceNumber(); - m_stateObject = 0; + m_stateObject = nullptr; m_documentSequenceNumber = generateSequenceNumber(); - m_formData = 0; + m_formData = nullptr; m_formContentType = String(); clearChildren(); @@ -259,11 +208,6 @@ const String& HistoryItem::target() const return m_target; } -const String& HistoryItem::parent() const -{ - return m_parent; -} - void HistoryItem::setAlternateTitle(const String& alternateTitle) { m_displayTitle = alternateTitle; @@ -283,7 +227,7 @@ void HistoryItem::setURLString(const String& urlString) void HistoryItem::setURL(const URL& url) { - pageCache()->remove(this); + PageCache::singleton().remove(*this); setURLString(url.string()); clearDocumentState(); } @@ -312,25 +256,19 @@ void HistoryItem::setTarget(const String& target) notifyHistoryItemChanged(this); } -void HistoryItem::setParent(const String& parent) -{ - m_parent = parent; -} - -const IntPoint& HistoryItem::scrollPoint() const +const IntPoint& HistoryItem::scrollPosition() const { - return m_scrollPoint; + return m_scrollPosition; } -void HistoryItem::setScrollPoint(const IntPoint& point) +void HistoryItem::setScrollPosition(const IntPoint& position) { - m_scrollPoint = point; + m_scrollPosition = position; } -void HistoryItem::clearScrollPoint() +void HistoryItem::clearScrollPosition() { - m_scrollPoint.setX(0); - m_scrollPoint.setY(0); + m_scrollPosition = IntPoint(); } float HistoryItem::pageScaleFactor() const @@ -358,6 +296,16 @@ void HistoryItem::clearDocumentState() m_documentState.clear(); } +void HistoryItem::setShouldOpenExternalURLsPolicy(ShouldOpenExternalURLsPolicy policy) +{ + m_shouldOpenExternalURLsPolicy = policy; +} + +ShouldOpenExternalURLsPolicy HistoryItem::shouldOpenExternalURLsPolicy() const +{ + return m_shouldOpenExternalURLsPolicy; +} + bool HistoryItem::isTargetItem() const { return m_isTargetItem; @@ -368,71 +316,52 @@ void HistoryItem::setIsTargetItem(bool flag) m_isTargetItem = flag; } -void HistoryItem::setStateObject(PassRefPtr<SerializedScriptValue> object) +void HistoryItem::setStateObject(RefPtr<SerializedScriptValue>&& object) { - m_stateObject = object; + m_stateObject = WTFMove(object); } -void HistoryItem::addChildItem(PassRefPtr<HistoryItem> child) +void HistoryItem::addChildItem(Ref<HistoryItem>&& child) { ASSERT(!childItemWithTarget(child->target())); - m_children.append(child); + m_children.append(WTFMove(child)); } -void HistoryItem::setChildItem(PassRefPtr<HistoryItem> child) +void HistoryItem::setChildItem(Ref<HistoryItem>&& child) { ASSERT(!child->isTargetItem()); unsigned size = m_children.size(); for (unsigned i = 0; i < size; ++i) { if (m_children[i]->target() == child->target()) { child->setIsTargetItem(m_children[i]->isTargetItem()); - m_children[i] = child; + m_children[i] = WTFMove(child); return; } } - m_children.append(child); + m_children.append(WTFMove(child)); } -HistoryItem* HistoryItem::childItemWithTarget(const String& target) const +HistoryItem* HistoryItem::childItemWithTarget(const String& target) { unsigned size = m_children.size(); for (unsigned i = 0; i < size; ++i) { if (m_children[i]->target() == target) - return m_children[i].get(); + return m_children[i].ptr(); } - return 0; + return nullptr; } -HistoryItem* HistoryItem::childItemWithDocumentSequenceNumber(long long number) const +HistoryItem* HistoryItem::childItemWithDocumentSequenceNumber(long long number) { unsigned size = m_children.size(); for (unsigned i = 0; i < size; ++i) { if (m_children[i]->documentSequenceNumber() == number) - return m_children[i].get(); + return m_children[i].ptr(); } - return 0; -} - -// <rdar://problem/4895849> HistoryItem::findTargetItem() should be replaced with a non-recursive method. -HistoryItem* HistoryItem::findTargetItem() -{ - if (m_isTargetItem) - return this; - unsigned size = m_children.size(); - for (unsigned i = 0; i < size; ++i) { - if (HistoryItem* match = m_children[i]->targetItem()) - return match; - } - return 0; -} - -HistoryItem* HistoryItem::targetItem() -{ - HistoryItem* foundItem = findTargetItem(); - return foundItem ? foundItem : this; + return nullptr; } -const HistoryItemVector& HistoryItem::children() const +const Vector<Ref<HistoryItem>>& HistoryItem::children() const { return m_children; } @@ -447,49 +376,37 @@ void HistoryItem::clearChildren() m_children.clear(); } -bool HistoryItem::isAncestorOf(const HistoryItem* item) const -{ - for (size_t i = 0; i < m_children.size(); ++i) { - HistoryItem* child = m_children[i].get(); - if (child == item) - return true; - if (child->isAncestorOf(item)) - return true; - } - return false; -} - // We do same-document navigation if going to a different item and if either of the following is true: // - The other item corresponds to the same document (for history entries created via pushState or fragment changes). // - The other item corresponds to the same set of documents, including frames (for history entries created via regular navigation) -bool HistoryItem::shouldDoSameDocumentNavigationTo(HistoryItem* otherItem) const +bool HistoryItem::shouldDoSameDocumentNavigationTo(HistoryItem& otherItem) const { - if (this == otherItem) + if (this == &otherItem) return false; - if (stateObject() || otherItem->stateObject()) - return documentSequenceNumber() == otherItem->documentSequenceNumber(); + if (stateObject() || otherItem.stateObject()) + return documentSequenceNumber() == otherItem.documentSequenceNumber(); - if ((url().hasFragmentIdentifier() || otherItem->url().hasFragmentIdentifier()) && equalIgnoringFragmentIdentifier(url(), otherItem->url())) - return documentSequenceNumber() == otherItem->documentSequenceNumber(); + if ((url().hasFragmentIdentifier() || otherItem.url().hasFragmentIdentifier()) && equalIgnoringFragmentIdentifier(url(), otherItem.url())) + return documentSequenceNumber() == otherItem.documentSequenceNumber(); return hasSameDocumentTree(otherItem); } // 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 +bool HistoryItem::hasSameDocumentTree(HistoryItem& otherItem) const { - if (documentSequenceNumber() != otherItem->documentSequenceNumber()) + if (documentSequenceNumber() != otherItem.documentSequenceNumber()) return false; - if (children().size() != otherItem->children().size()) + if (children().size() != otherItem.children().size()) return false; for (size_t i = 0; i < children().size(); i++) { - HistoryItem* child = children()[i].get(); - HistoryItem* otherChild = otherItem->childItemWithDocumentSequenceNumber(child->documentSequenceNumber()); - if (!otherChild || !child->hasSameDocumentTree(otherChild)) + auto& child = children()[i].get(); + auto* otherChild = otherItem.childItemWithDocumentSequenceNumber(child.documentSequenceNumber()); + if (!otherChild || !child.hasSameDocumentTree(*otherChild)) return false; } @@ -498,16 +415,16 @@ bool HistoryItem::hasSameDocumentTree(HistoryItem* otherItem) const // 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 +bool HistoryItem::hasSameFrames(HistoryItem& otherItem) const { - if (target() != otherItem->target()) + if (target() != otherItem.target()) return false; - if (children().size() != otherItem->children().size()) + if (children().size() != otherItem.children().size()) return false; for (size_t i = 0; i < children().size(); i++) { - if (!otherItem->childItemWithTarget(children()[i]->target())) + if (!otherItem.childItemWithTarget(children()[i]->target())) return false; } @@ -523,20 +440,20 @@ void HistoryItem::setFormInfoFromRequest(const ResourceRequest& request) { m_referrer = request.httpReferrer(); - if (equalIgnoringCase(request.httpMethod(), "POST")) { + if (equalLettersIgnoringASCIICase(request.httpMethod(), "post")) { // FIXME: Eventually we have to make this smart enough to handle the case where // we have a stream for the body to handle the "data interspersed with files" feature. m_formData = request.httpBody(); m_formContentType = request.httpContentType(); } else { - m_formData = 0; + m_formData = nullptr; m_formContentType = String(); } } -void HistoryItem::setFormData(PassRefPtr<FormData> formData) +void HistoryItem::setFormData(RefPtr<FormData>&& formData) { - m_formData = formData; + m_formData = WTFMove(formData); } void HistoryItem::setFormContentType(const String& formContentType) @@ -549,266 +466,15 @@ FormData* HistoryItem::formData() return m_formData.get(); } -bool HistoryItem::isCurrentDocument(Document* doc) const +bool HistoryItem::isCurrentDocument(Document& document) const { // FIXME: We should find a better way to check if this is the current document. - return equalIgnoringFragmentIdentifier(url(), doc->url()); -} - -void HistoryItem::addRedirectURL(const String& url) -{ - if (!m_redirectURLs) - m_redirectURLs = std::make_unique<Vector<String>>(); - - // Our API allows us to store all the URLs in the redirect chain, but for - // now we only have a use for the final URL. - (*m_redirectURLs).resize(1); - (*m_redirectURLs)[0] = url; -} - -Vector<String>* HistoryItem::redirectURLs() const -{ - return m_redirectURLs.get(); -} - -void HistoryItem::setRedirectURLs(std::unique_ptr<Vector<String>> redirectURLs) -{ - m_redirectURLs = std::move(redirectURLs); -} - -void HistoryItem::encodeBackForwardTree(Encoder& encoder) const -{ - encoder.encodeUInt32(backForwardTreeEncodingVersion); - - encodeBackForwardTreeNode(encoder); -} - -void HistoryItem::encodeBackForwardTree(KeyedEncoder& encoder) const -{ - encoder.encodeUInt32("version", backForwardTreeEncodingVersion); - - encoder.encodeObject("root", *this, [](KeyedEncoder& encoder, const HistoryItem& item) { - item.encodeBackForwardTreeNode(encoder); - }); + return equalIgnoringFragmentIdentifier(url(), document.url()); } -void HistoryItem::encodeBackForwardTreeNode(Encoder& encoder) const +void HistoryItem::notifyChanged() { - size_t size = m_children.size(); - encoder.encodeUInt64(size); - for (size_t i = 0; i < size; ++i) { - const HistoryItem& child = *m_children[i]; - - encoder.encodeString(child.m_originalURLString); - - encoder.encodeString(child.m_urlString); - - child.encodeBackForwardTreeNode(encoder); - } - - encoder.encodeInt64(m_documentSequenceNumber); - - size = m_documentState.size(); - encoder.encodeUInt64(size); - for (size_t i = 0; i < size; ++i) - encoder.encodeString(m_documentState[i]); - - encoder.encodeString(m_formContentType); - - encoder.encodeBool(m_formData); - if (m_formData) - m_formData->encode(encoder); - - encoder.encodeInt64(m_itemSequenceNumber); - - encoder.encodeString(m_referrer); - - encoder.encodeInt32(m_scrollPoint.x()); - encoder.encodeInt32(m_scrollPoint.y()); - - encoder.encodeFloat(m_pageScaleFactor); - - encoder.encodeBool(m_stateObject); - if (m_stateObject) - encoder.encodeBytes(m_stateObject->data().data(), m_stateObject->data().size()); - - encoder.encodeString(m_target); -} - -void HistoryItem::encodeBackForwardTreeNode(KeyedEncoder& encoder) const -{ - encoder.encodeObjects("children", m_children.begin(), m_children.end(), [](KeyedEncoder& encoder, const RefPtr<HistoryItem>& child) { - encoder.encodeString("originalURLString", child->m_originalURLString); - encoder.encodeString("urlString", child->m_urlString); - - child->encodeBackForwardTreeNode(encoder); - }); - - encoder.encodeInt64("documentSequenceNumber", m_documentSequenceNumber); - - encoder.encodeObjects("documentState", m_documentState.begin(), m_documentState.end(), [](KeyedEncoder& encoder, const String& string) { - encoder.encodeString("string", string); - }); - - encoder.encodeString("formContentType", m_formContentType); - - encoder.encodeConditionalObject("formData", m_formData.get(), [](KeyedEncoder&, const FormData&) { - // FIXME: Implement. - }); - - encoder.encodeInt64("itemSequenceNumber", m_itemSequenceNumber); - - encoder.encodeString("referrer", m_referrer); - - encoder.encodeObject("scrollPoint", m_scrollPoint, [](KeyedEncoder& encoder, const IntPoint& scrollPoint) { - encoder.encodeInt32("x", scrollPoint.x()); - encoder.encodeInt32("y", scrollPoint.y()); - }); - - encoder.encodeFloat("pageScaleFactor", m_pageScaleFactor); - - encoder.encodeConditionalObject("stateObject", m_stateObject.get(), [](KeyedEncoder& encoder, const SerializedScriptValue& stateObject) { - encoder.encodeBytes("data", stateObject.data().data(), stateObject.data().size()); - }); - - encoder.encodeString("target", m_target); -} - -struct DecodeRecursionStackElement { - RefPtr<HistoryItem> node; - size_t i; - uint64_t size; - - DecodeRecursionStackElement(PassRefPtr<HistoryItem> node, size_t i, uint64_t size) - : node(node) - , i(i) - , size(size) - { - } -}; - -PassRefPtr<HistoryItem> HistoryItem::decodeBackForwardTree(const String& topURLString, const String& topTitle, const String& topOriginalURLString, Decoder& decoder) -{ - // Since the data stream is not trusted, the decode has to be non-recursive. - // We don't want bad data to cause a stack overflow. - - uint32_t version; - if (!decoder.decodeUInt32(version)) - return 0; - if (version != backForwardTreeEncodingVersion) - return 0; - - String urlString = topURLString; - String title = topTitle; - String originalURLString = topOriginalURLString; - - Vector<DecodeRecursionStackElement, 16> recursionStack; - -recurse: - RefPtr<HistoryItem> node = create(urlString, title); - - node->setOriginalURLString(originalURLString); - - title = String(); - - uint64_t size; - if (!decoder.decodeUInt64(size)) - return 0; - size_t i; - RefPtr<HistoryItem> child; - for (i = 0; i < size; ++i) { - if (!decoder.decodeString(originalURLString)) - return 0; - - if (!decoder.decodeString(urlString)) - return 0; - - recursionStack.append(DecodeRecursionStackElement(node.release(), i, size)); - goto recurse; - -resume: - node->m_children.append(child.release()); - } - - if (!decoder.decodeInt64(node->m_documentSequenceNumber)) - return 0; - - if (!decoder.decodeUInt64(size)) - return 0; - for (i = 0; i < size; ++i) { - String state; - if (!decoder.decodeString(state)) - return 0; - node->m_documentState.append(state); - } - - if (!decoder.decodeString(node->m_formContentType)) - return 0; - - bool hasFormData; - if (!decoder.decodeBool(hasFormData)) - return 0; - if (hasFormData) { - node->m_formData = FormData::decode(decoder); - if (!node->m_formData) - return 0; - } - - if (!decoder.decodeInt64(node->m_itemSequenceNumber)) - return 0; - - if (!decoder.decodeString(node->m_referrer)) - return 0; - - int32_t x; - if (!decoder.decodeInt32(x)) - return 0; - int32_t y; - if (!decoder.decodeInt32(y)) - return 0; - node->m_scrollPoint = IntPoint(x, y); - - if (!decoder.decodeFloat(node->m_pageScaleFactor)) - return 0; - - bool hasStateObject; - if (!decoder.decodeBool(hasStateObject)) - return 0; - if (hasStateObject) { - Vector<uint8_t> bytes; - if (!decoder.decodeBytes(bytes)) - return 0; - node->m_stateObject = SerializedScriptValue::adopt(bytes); - } - - if (!decoder.decodeString(node->m_target)) - return 0; - - // Simulate recursion with our own stack. - if (!recursionStack.isEmpty()) { - DecodeRecursionStackElement& element = recursionStack.last(); - child = node.release(); - node = element.node.release(); - i = element.i; - size = element.size; - recursionStack.removeLast(); - goto resume; - } - - return node.release(); -} - -PassRefPtr<HistoryItem> HistoryItem::decodeBackForwardTree(const String&, const String&, const String&, KeyedDecoder& decoder) -{ - uint32_t version; - if (!decoder.decodeUInt32("version", version)) - return nullptr; - - if (version != backForwardTreeEncodingVersion) - return nullptr; - - // FIXME: Implement. - return nullptr; + notifyHistoryItemChanged(this); } #ifndef NDEBUG |