Reduce PassRefPtr in WebKit2 - 3
[WebKit-https.git] / Source / WebKit2 / WebProcess / WebCoreSupport / SessionStateConversion.cpp
1 /*
2  * Copyright (C) 2014 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "SessionStateConversion.h"
28
29 #include "SessionState.h"
30 #include <WebCore/BlobData.h>
31 #include <WebCore/FormData.h>
32 #include <WebCore/HistoryItem.h>
33
34 using namespace WebCore;
35
36 namespace WebKit {
37
38 static HTTPBody toHTTPBody(const FormData& formData)
39 {
40     HTTPBody httpBody;
41
42     for (const auto& formDataElement : formData.elements()) {
43         HTTPBody::Element element;
44
45         switch (formDataElement.m_type) {
46         case FormDataElement::Type::Data:
47             element.type = HTTPBody::Element::Type::Data;
48             element.data = formDataElement.m_data;
49             break;
50
51         case FormDataElement::Type::EncodedFile:
52             element.filePath = formDataElement.m_filename;
53             element.fileStart = formDataElement.m_fileStart;
54             if (formDataElement.m_fileLength != BlobDataItem::toEndOfFile)
55                 element.fileLength = formDataElement.m_fileLength;
56             if (formDataElement.m_expectedFileModificationTime != invalidFileTime())
57                 element.expectedFileModificationTime = formDataElement.m_expectedFileModificationTime;
58             break;
59
60         case FormDataElement::Type::EncodedBlob:
61             element.blobURLString = formDataElement.m_url.string();
62             break;
63         }
64
65         httpBody.elements.append(WTF::move(element));
66     }
67
68     return httpBody;
69 }
70
71 static FrameState toFrameState(const HistoryItem& historyItem)
72 {
73     FrameState frameState;
74
75     frameState.urlString = historyItem.urlString();
76     frameState.originalURLString = historyItem.originalURLString();
77     frameState.referrer = historyItem.referrer();
78     frameState.target = historyItem.target();
79
80     frameState.documentState = historyItem.documentState();
81     if (RefPtr<SerializedScriptValue> stateObject = historyItem.stateObject())
82         frameState.stateObjectData = stateObject->data();
83
84     frameState.documentSequenceNumber = historyItem.documentSequenceNumber();
85     frameState.itemSequenceNumber = historyItem.itemSequenceNumber();
86
87     frameState.scrollPoint = historyItem.scrollPoint();
88     frameState.pageScaleFactor = historyItem.pageScaleFactor();
89
90     if (FormData* formData = const_cast<HistoryItem&>(historyItem).formData()) {
91         HTTPBody httpBody = toHTTPBody(*formData);
92         httpBody.contentType = historyItem.formContentType();
93
94         frameState.httpBody = WTF::move(httpBody);
95     }
96
97 #if PLATFORM(IOS)
98     frameState.exposedContentRect = historyItem.exposedContentRect();
99     frameState.unobscuredContentRect = historyItem.unobscuredContentRect();
100     frameState.minimumLayoutSizeInScrollViewCoordinates = historyItem.minimumLayoutSizeInScrollViewCoordinates();
101     frameState.contentSize = historyItem.contentSize();
102     frameState.scaleIsInitial = historyItem.scaleIsInitial();
103 #endif
104
105     for (auto& childHistoryItem : historyItem.children()) {
106         FrameState childFrameState = toFrameState(childHistoryItem);
107         frameState.children.append(WTF::move(childFrameState));
108     }
109
110     return frameState;
111 }
112
113 PageState toPageState(const WebCore::HistoryItem& historyItem)
114 {
115     PageState pageState;
116
117     pageState.title = historyItem.title();
118     pageState.mainFrameState = toFrameState(historyItem);
119
120     return pageState;
121 }
122
123 static PassRefPtr<FormData> toFormData(const HTTPBody& httpBody)
124 {
125     RefPtr<FormData> formData = FormData::create();
126
127     for (const auto& element : httpBody.elements) {
128         switch (element.type) {
129         case HTTPBody::Element::Type::Data:
130             formData->appendData(element.data.data(), element.data.size());
131             break;
132
133         case HTTPBody::Element::Type::File:
134             formData->appendFileRange(element.filePath, element.fileStart, element.fileLength.valueOr(BlobDataItem::toEndOfFile), element.expectedFileModificationTime.valueOr(invalidFileTime()));
135             break;
136
137         case HTTPBody::Element::Type::Blob:
138             formData->appendBlob(URL(URL(), element.blobURLString));
139             break;
140         }
141     }
142
143     return formData.release();
144 }
145
146 static void applyFrameState(HistoryItem& historyItem, const FrameState& frameState)
147 {
148     historyItem.setOriginalURLString(frameState.originalURLString);
149     historyItem.setReferrer(frameState.referrer);
150     historyItem.setTarget(frameState.target);
151
152     historyItem.setDocumentState(frameState.documentState);
153
154     if (frameState.stateObjectData) {
155         Vector<uint8_t> stateObjectData = frameState.stateObjectData.value();
156         historyItem.setStateObject(SerializedScriptValue::adopt(stateObjectData));
157     }
158
159     historyItem.setDocumentSequenceNumber(frameState.documentSequenceNumber);
160     historyItem.setItemSequenceNumber(frameState.itemSequenceNumber);
161
162     historyItem.setScrollPoint(frameState.scrollPoint);
163     historyItem.setPageScaleFactor(frameState.pageScaleFactor);
164
165     if (frameState.httpBody) {
166         const auto& httpBody = frameState.httpBody.value();
167         historyItem.setFormContentType(httpBody.contentType);
168
169         historyItem.setFormData(toFormData(httpBody));
170     }
171
172 #if PLATFORM(IOS)
173     historyItem.setExposedContentRect(frameState.exposedContentRect);
174     historyItem.setUnobscuredContentRect(frameState.unobscuredContentRect);
175     historyItem.setMinimumLayoutSizeInScrollViewCoordinates(frameState.minimumLayoutSizeInScrollViewCoordinates);
176     historyItem.setContentSize(frameState.contentSize);
177     historyItem.setScaleIsInitial(frameState.scaleIsInitial);
178 #endif
179
180     for (const auto& childFrameState : frameState.children) {
181         Ref<HistoryItem> childHistoryItem = HistoryItem::create(childFrameState.urlString, String());
182         applyFrameState(childHistoryItem, childFrameState);
183
184         historyItem.addChildItem(WTF::move(childHistoryItem));
185     }
186 }
187
188 Ref<HistoryItem> toHistoryItem(const PageState& pageState)
189 {
190     Ref<HistoryItem> historyItem = HistoryItem::create(pageState.mainFrameState.urlString, pageState.title);
191     applyFrameState(historyItem, pageState.mainFrameState);
192
193     return historyItem;
194 }
195
196 } // namespace WebKit