OLD | NEW |
| (Empty) |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "content/public/renderer/history_item_serialization.h" | |
6 | |
7 #include "content/common/page_state_serialization.h" | |
8 #include "content/public/common/page_state.h" | |
9 #include "third_party/WebKit/public/platform/WebHTTPBody.h" | |
10 #include "third_party/WebKit/public/platform/WebPoint.h" | |
11 #include "third_party/WebKit/public/platform/WebString.h" | |
12 #include "third_party/WebKit/public/platform/WebVector.h" | |
13 #include "third_party/WebKit/public/web/WebHistoryItem.h" | |
14 #include "third_party/WebKit/public/web/WebSerializedScriptValue.h" | |
15 | |
16 using blink::WebHTTPBody; | |
17 using blink::WebHistoryItem; | |
18 using blink::WebSerializedScriptValue; | |
19 using blink::WebString; | |
20 using blink::WebVector; | |
21 | |
22 namespace content { | |
23 namespace { | |
24 | |
25 void ToNullableString16Vector(const WebVector<WebString>& input, | |
26 std::vector<base::NullableString16>* output) { | |
27 output->reserve(input.size()); | |
28 for (size_t i = 0; i < input.size(); ++i) | |
29 output->push_back(input[i]); | |
30 } | |
31 | |
32 void ToExplodedHttpBodyElement(const WebHTTPBody::Element& input, | |
33 ExplodedHttpBodyElement* output) { | |
34 switch (input.type) { | |
35 case WebHTTPBody::Element::TypeData: | |
36 output->data.assign(input.data.data(), input.data.size()); | |
37 break; | |
38 case WebHTTPBody::Element::TypeFile: | |
39 output->file_path = input.filePath; | |
40 output->file_start = input.fileStart; | |
41 output->file_length = input.fileLength; | |
42 output->file_modification_time = input.modificationTime; | |
43 break; | |
44 case WebHTTPBody::Element::TypeFileSystemURL: | |
45 output->filesystem_url = input.fileSystemURL; | |
46 output->file_start = input.fileStart; | |
47 output->file_length = input.fileLength; | |
48 output->file_modification_time = input.modificationTime; | |
49 break; | |
50 case WebHTTPBody::Element::TypeBlob: | |
51 output->blob_uuid = input.blobUUID.utf8(); | |
52 break; | |
53 } | |
54 } | |
55 | |
56 void AppendHTTPBodyElement(const ExplodedHttpBodyElement& element, | |
57 WebHTTPBody* http_body) { | |
58 switch (element.type) { | |
59 case WebHTTPBody::Element::TypeData: | |
60 http_body->appendData(element.data); | |
61 break; | |
62 case WebHTTPBody::Element::TypeFile: | |
63 http_body->appendFileRange( | |
64 element.file_path, | |
65 element.file_start, | |
66 element.file_length, | |
67 element.file_modification_time); | |
68 break; | |
69 case WebHTTPBody::Element::TypeFileSystemURL: | |
70 http_body->appendFileSystemURLRange( | |
71 element.filesystem_url, | |
72 element.file_start, | |
73 element.file_length, | |
74 element.file_modification_time); | |
75 break; | |
76 case WebHTTPBody::Element::TypeBlob: | |
77 http_body->appendBlob(WebString::fromUTF8(element.blob_uuid)); | |
78 break; | |
79 } | |
80 } | |
81 | |
82 bool RecursivelyGenerateFrameState(const WebHistoryItem& item, | |
83 ExplodedFrameState* state) { | |
84 state->url_string = item.urlString(); | |
85 state->referrer = item.referrer(); | |
86 state->referrer_policy = item.referrerPolicy(); | |
87 state->target = item.target(); | |
88 if (!item.stateObject().isNull()) | |
89 state->state_object = item.stateObject().toString(); | |
90 state->scroll_offset = item.scrollOffset(); | |
91 state->item_sequence_number = item.itemSequenceNumber(); | |
92 state->document_sequence_number = | |
93 item.documentSequenceNumber(); | |
94 state->page_scale_factor = item.pageScaleFactor(); | |
95 ToNullableString16Vector(item.documentState(), &state->document_state); | |
96 | |
97 state->http_body.http_content_type = item.httpContentType(); | |
98 const WebHTTPBody& http_body = item.httpBody(); | |
99 if (!(state->http_body.is_null = http_body.isNull())) { | |
100 state->http_body.identifier = http_body.identifier(); | |
101 state->http_body.elements.resize(http_body.elementCount()); | |
102 for (size_t i = 0; i < http_body.elementCount(); ++i) { | |
103 WebHTTPBody::Element element; | |
104 http_body.elementAt(i, element); | |
105 ToExplodedHttpBodyElement(element, &state->http_body.elements[i]); | |
106 } | |
107 state->http_body.contains_passwords = http_body.containsPasswordData(); | |
108 } | |
109 | |
110 const WebVector<WebHistoryItem>& children = item.children(); | |
111 state->children.resize(children.size()); | |
112 for (size_t i = 0; i < children.size(); ++i) { | |
113 if (!RecursivelyGenerateFrameState(children[i], &state->children[i])) | |
114 return false; | |
115 } | |
116 | |
117 return true; | |
118 } | |
119 | |
120 bool RecursivelyGenerateHistoryItem(const ExplodedFrameState& state, | |
121 WebHistoryItem* item) { | |
122 item->setURLString(state.url_string); | |
123 item->setReferrer(state.referrer, state.referrer_policy); | |
124 item->setTarget(state.target); | |
125 if (!state.state_object.is_null()) { | |
126 item->setStateObject( | |
127 WebSerializedScriptValue::fromString(state.state_object)); | |
128 } | |
129 item->setDocumentState(state.document_state); | |
130 item->setScrollOffset(state.scroll_offset); | |
131 item->setPageScaleFactor(state.page_scale_factor); | |
132 | |
133 // These values are generated at WebHistoryItem construction time, and we | |
134 // only want to override those new values with old values if the old values | |
135 // are defined. A value of 0 means undefined in this context. | |
136 if (state.item_sequence_number) | |
137 item->setItemSequenceNumber(state.item_sequence_number); | |
138 if (state.document_sequence_number) | |
139 item->setDocumentSequenceNumber(state.document_sequence_number); | |
140 | |
141 item->setHTTPContentType(state.http_body.http_content_type); | |
142 if (!state.http_body.is_null) { | |
143 WebHTTPBody http_body; | |
144 http_body.initialize(); | |
145 http_body.setIdentifier(state.http_body.identifier); | |
146 for (size_t i = 0; i < state.http_body.elements.size(); ++i) | |
147 AppendHTTPBodyElement(state.http_body.elements[i], &http_body); | |
148 item->setHTTPBody(http_body); | |
149 } | |
150 | |
151 for (size_t i = 0; i < state.children.size(); ++i) { | |
152 WebHistoryItem child_item; | |
153 child_item.initialize(); | |
154 if (!RecursivelyGenerateHistoryItem(state.children[i], &child_item)) | |
155 return false; | |
156 item->appendToChildren(child_item); | |
157 } | |
158 | |
159 return true; | |
160 } | |
161 | |
162 } // namespace | |
163 | |
164 PageState HistoryItemToPageState(const WebHistoryItem& item) { | |
165 ExplodedPageState state; | |
166 ToNullableString16Vector(item.getReferencedFilePaths(), | |
167 &state.referenced_files); | |
168 | |
169 if (!RecursivelyGenerateFrameState(item, &state.top)) | |
170 return PageState(); | |
171 | |
172 std::string encoded_data; | |
173 if (!EncodePageState(state, &encoded_data)) | |
174 return PageState(); | |
175 | |
176 return PageState::CreateFromEncodedData(encoded_data); | |
177 } | |
178 | |
179 WebHistoryItem PageStateToHistoryItem(const PageState& page_state) { | |
180 ExplodedPageState state; | |
181 if (!DecodePageState(page_state.ToEncodedData(), &state)) | |
182 return WebHistoryItem(); | |
183 | |
184 WebHistoryItem item; | |
185 item.initialize(); | |
186 if (!RecursivelyGenerateHistoryItem(state.top, &item)) | |
187 return WebHistoryItem(); | |
188 | |
189 return item; | |
190 } | |
191 | |
192 } // namespace content | |
OLD | NEW |