/* * 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 #include #include 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 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).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 toFormData(const HTTPBody& httpBody) { RefPtr 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.valueOr(BlobDataItem::toEndOfFile), element.expectedFileModificationTime.valueOr(invalidFileTime())); break; case HTTPBody::Element::Type::Blob: formData->appendBlob(URL(URL(), element.blobURLString)); break; } } return formData.release(); } 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 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 childHistoryItem = HistoryItem::create(childFrameState.urlString, String()); applyFrameState(childHistoryItem, childFrameState); historyItem.addChildItem(WTFMove(childHistoryItem)); } } Ref toHistoryItem(const PageState& pageState) { Ref historyItem = HistoryItem::create(pageState.mainFrameState.urlString, pageState.title); historyItem->setShouldOpenExternalURLsPolicy(pageState.shouldOpenExternalURLsPolicy); applyFrameState(historyItem, pageState.mainFrameState); return historyItem; } } // namespace WebKit