diff options
Diffstat (limited to 'Source/WebKit2/WebProcess/WebCoreSupport/SessionStateConversion.cpp')
-rw-r--r-- | Source/WebKit2/WebProcess/WebCoreSupport/SessionStateConversion.cpp | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/SessionStateConversion.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/SessionStateConversion.cpp new file mode 100644 index 000000000..28f757ffe --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/SessionStateConversion.cpp @@ -0,0 +1,198 @@ +/* + * Copyright (C) 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 + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * 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 INC. AND ITS CONTRIBUTORS ``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 INC. OR ITS 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 PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "SessionStateConversion.h" + +#include "SessionState.h" +#include <WebCore/BlobData.h> +#include <WebCore/FormData.h> +#include <WebCore/HistoryItem.h> + +using namespace WebCore; + +namespace WebKit { + +static HTTPBody toHTTPBody(const FormData& formData) +{ + HTTPBody httpBody; + + for (const auto& formDataElement : formData.elements()) { + HTTPBody::Element element; + + switch (formDataElement.m_type) { + case FormDataElement::Type::Data: + element.type = HTTPBody::Element::Type::Data; + element.data = formDataElement.m_data; + break; + + case FormDataElement::Type::EncodedFile: + element.filePath = formDataElement.m_filename; + element.fileStart = formDataElement.m_fileStart; + if (formDataElement.m_fileLength != BlobDataItem::toEndOfFile) + element.fileLength = formDataElement.m_fileLength; + if (formDataElement.m_expectedFileModificationTime != invalidFileTime()) + element.expectedFileModificationTime = formDataElement.m_expectedFileModificationTime; + break; + + case FormDataElement::Type::EncodedBlob: + element.blobURLString = formDataElement.m_url.string(); + break; + } + + httpBody.elements.append(WTFMove(element)); + } + + return httpBody; +} + +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.scrollPosition = historyItem.scrollPosition(); + frameState.pageScaleFactor = historyItem.pageScaleFactor(); + + if (FormData* formData = const_cast<HistoryItem&>(historyItem).formData()) { + HTTPBody httpBody = toHTTPBody(*formData); + httpBody.contentType = historyItem.formContentType(); + + frameState.httpBody = WTFMove(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(WTFMove(childFrameState)); + } + + return frameState; +} + +PageState toPageState(const WebCore::HistoryItem& historyItem) +{ + PageState pageState; + + pageState.title = historyItem.title(); + pageState.mainFrameState = toFrameState(historyItem); + pageState.shouldOpenExternalURLsPolicy = historyItem.shouldOpenExternalURLsPolicy(); + + return pageState; +} + +static PassRefPtr<FormData> toFormData(const HTTPBody& httpBody) +{ + auto formData = FormData::create(); + + for (const auto& element : httpBody.elements) { + switch (element.type) { + case HTTPBody::Element::Type::Data: + formData->appendData(element.data.data(), element.data.size()); + break; + + case HTTPBody::Element::Type::File: + formData->appendFileRange(element.filePath, element.fileStart, element.fileLength.value_or(BlobDataItem::toEndOfFile), element.expectedFileModificationTime.value_or(invalidFileTime())); + break; + + case HTTPBody::Element::Type::Blob: + formData->appendBlob(URL(URL(), element.blobURLString)); + break; + } + } + + return WTFMove(formData); +} + +static void applyFrameState(HistoryItem& historyItem, const FrameState& frameState) +{ + historyItem.setOriginalURLString(frameState.originalURLString); + historyItem.setReferrer(frameState.referrer); + historyItem.setTarget(frameState.target); + + historyItem.setDocumentState(frameState.documentState); + + if (frameState.stateObjectData) { + Vector<uint8_t> stateObjectData = frameState.stateObjectData.value(); + historyItem.setStateObject(SerializedScriptValue::adopt(WTFMove(stateObjectData))); + } + + historyItem.setDocumentSequenceNumber(frameState.documentSequenceNumber); + historyItem.setItemSequenceNumber(frameState.itemSequenceNumber); + + historyItem.setScrollPosition(frameState.scrollPosition); + historyItem.setPageScaleFactor(frameState.pageScaleFactor); + + if (frameState.httpBody) { + const auto& httpBody = frameState.httpBody.value(); + historyItem.setFormContentType(httpBody.contentType); + + historyItem.setFormData(toFormData(httpBody)); + } + +#if PLATFORM(IOS) + historyItem.setExposedContentRect(frameState.exposedContentRect); + historyItem.setUnobscuredContentRect(frameState.unobscuredContentRect); + historyItem.setMinimumLayoutSizeInScrollViewCoordinates(frameState.minimumLayoutSizeInScrollViewCoordinates); + historyItem.setContentSize(frameState.contentSize); + historyItem.setScaleIsInitial(frameState.scaleIsInitial); +#endif + + for (const auto& childFrameState : frameState.children) { + Ref<HistoryItem> childHistoryItem = HistoryItem::create(childFrameState.urlString, String()); + applyFrameState(childHistoryItem, childFrameState); + + historyItem.addChildItem(WTFMove(childHistoryItem)); + } +} + +Ref<HistoryItem> toHistoryItem(const PageState& pageState) +{ + Ref<HistoryItem> historyItem = HistoryItem::create(pageState.mainFrameState.urlString, pageState.title); + historyItem->setShouldOpenExternalURLsPolicy(pageState.shouldOpenExternalURLsPolicy); + applyFrameState(historyItem, pageState.mainFrameState); + + return historyItem; +} + +} // namespace WebKit |