| 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 |