1 // Copyright (c) 2012 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.
5 #include "chrome/common/extensions/extension_localization_peer.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "base/string_util.h"
9 #include "chrome/common/extensions/extension_messages.h"
10 #include "chrome/common/extensions/message_bundle.h"
11 #include "chrome/common/url_constants.h"
12 #include "extensions/common/constants.h"
13 #include "grit/generated_resources.h"
14 #include "net/base/net_errors.h"
15 #include "net/http/http_response_headers.h"
16 #include "webkit/glue/webkit_glue.h"
18 ExtensionLocalizationPeer::ExtensionLocalizationPeer(
19 webkit_glue::ResourceLoaderBridge::Peer
* peer
,
20 IPC::Sender
* message_sender
,
21 const GURL
& request_url
)
22 : original_peer_(peer
),
23 message_sender_(message_sender
),
24 request_url_(request_url
) {
27 ExtensionLocalizationPeer::~ExtensionLocalizationPeer() {
31 ExtensionLocalizationPeer
*
32 ExtensionLocalizationPeer::CreateExtensionLocalizationPeer(
33 webkit_glue::ResourceLoaderBridge::Peer
* peer
,
34 IPC::Sender
* message_sender
,
35 const std::string
& mime_type
,
36 const GURL
& request_url
) {
37 // Return NULL if content is not text/css or it doesn't belong to extension
39 return (request_url
.SchemeIs(extensions::kExtensionScheme
) &&
40 StartsWithASCII(mime_type
, "text/css", false)) ?
41 new ExtensionLocalizationPeer(peer
, message_sender
, request_url
) : NULL
;
44 void ExtensionLocalizationPeer::OnUploadProgress(
45 uint64 position
, uint64 size
) {
49 bool ExtensionLocalizationPeer::OnReceivedRedirect(
51 const webkit_glue::ResourceResponseInfo
& info
,
52 bool* has_new_first_party_for_cookies
,
53 GURL
* new_first_party_for_cookies
) {
58 void ExtensionLocalizationPeer::OnReceivedResponse(
59 const webkit_glue::ResourceResponseInfo
& info
) {
60 response_info_
= info
;
63 void ExtensionLocalizationPeer::OnReceivedData(const char* data
,
65 int encoded_data_length
) {
66 data_
.append(data
, data_length
);
69 void ExtensionLocalizationPeer::OnCompletedRequest(
71 bool was_ignored_by_handler
,
72 const std::string
& security_info
,
73 const base::TimeTicks
& completion_time
) {
74 // Make sure we delete ourselves at the end of this call.
75 scoped_ptr
<ExtensionLocalizationPeer
> this_deleter(this);
77 // Give sub-classes a chance at altering the data.
78 if (error_code
!= net::OK
) {
79 // We failed to load the resource.
80 original_peer_
->OnReceivedResponse(response_info_
);
81 original_peer_
->OnCompletedRequest(net::ERR_ABORTED
, false, security_info
,
88 original_peer_
->OnReceivedResponse(response_info_
);
90 original_peer_
->OnReceivedData(data_
.data(),
91 static_cast<int>(data_
.size()),
93 original_peer_
->OnCompletedRequest(error_code
, was_ignored_by_handler
,
94 security_info
, completion_time
);
97 void ExtensionLocalizationPeer::ReplaceMessages() {
98 if (!message_sender_
|| data_
.empty())
101 if (!request_url_
.is_valid())
104 std::string extension_id
= request_url_
.host();
105 extensions::L10nMessagesMap
* l10n_messages
=
106 extensions::GetL10nMessagesMap(extension_id
);
107 if (!l10n_messages
) {
108 extensions::L10nMessagesMap messages
;
109 message_sender_
->Send(new ExtensionHostMsg_GetMessageBundle(
110 extension_id
, &messages
));
112 // Save messages we got, so we don't have to ask again.
113 // Messages map is never empty, it contains at least @@extension_id value.
114 extensions::ExtensionToL10nMessagesMap
& l10n_messages_map
=
115 *extensions::GetExtensionToL10nMessagesMap();
116 l10n_messages_map
[extension_id
] = messages
;
118 l10n_messages
= extensions::GetL10nMessagesMap(extension_id
);
122 if (extensions::MessageBundle::ReplaceMessagesWithExternalDictionary(
123 *l10n_messages
, &data_
, &error
)) {
124 data_
.resize(data_
.size());