Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(232)

Side by Side Diff: chrome/renderer/extensions/chrome_webstore_bindings.cc

Issue 7621032: Initial inline web store install bindings. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 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 "chrome/renderer/extensions/chrome_webstore_bindings.h"
6
7 #include "base/string16.h"
Aaron Boodman 2011/08/17 04:53:03 I don't see any instance of 'string16' in this fil
Mihai Parparita -not on Chrome 2011/08/17 23:00:16 Removed this and a couple of other unneeded #inclu
8 #include "base/string_util.h"
9 #include "base/utf_string_conversions.h"
10 #include "base/values.h"
11 #include "chrome/common/extensions/extension.h"
12 #include "chrome/renderer/extensions/bindings_utils.h"
13 #include "chrome/renderer/extensions/extension_helper.h"
14 #include "content/renderer/render_view.h"
15 #include "googleurl/src/gurl.h"
16 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
17 #include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h"
18 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
19 #include "third_party/WebKit/Source/WebKit/chromium/public/WebNode.h"
20 #include "third_party/WebKit/Source/WebKit/chromium/public/WebNodeList.h"
21 #include "v8/include/v8.h"
22
23 using WebKit::WebDocument;
24 using WebKit::WebElement;
25 using WebKit::WebFrame;
26 using WebKit::WebNode;
27 using WebKit::WebNodeList;
28
29 const char kWebstoreLinkRelation[] = "chrome-webstore-item";
30
31 const char kNotInTopFrameError[] =
32 "Chrome Web Store installations can only be started by the top frame.";
33 const char kNotUserGestureError[] =
34 "Chrome Web Store installations can only be initated by a user gesture.";
35 const char kNoWebstoreItemLinkFoundError[] =
36 "No Chrome Web Store item link found.";
37 const char kInvalidWebstoreItemUrlError[] =
38 "Invalid Chrome Web Store item URL.";
39
40 namespace extensions_v8 {
41
42 static const char* const kWebstoreExtensionName = "v8/ChromeWebstore";
43
44 class ChromeWebstoreExtensionWrapper : public v8::Extension {
45 public:
46 ChromeWebstoreExtensionWrapper() :
47 v8::Extension(
48 kWebstoreExtensionName,
49 "var chrome;"
50 "if (!chrome)"
51 " chrome = {};"
52 "if (!chrome.webstore) {"
53 " chrome.webstore = new function() {"
54 " native function Install();"
55 " this.install = Install;"
56 " };"
57 "}") {
58 }
59
60 virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
61 v8::Handle<v8::String> name) {
62 if (name->Equals(v8::String::New("Install"))) {
63 return v8::FunctionTemplate::New(Install);
64 } else {
65 return v8::Handle<v8::FunctionTemplate>();
66 }
67 }
68
69 static v8::Handle<v8::Value> Install(const v8::Arguments& args) {
70 WebFrame* frame = WebFrame::frameForCurrentContext();
71 RenderView* render_view = bindings_utils::GetRenderViewForCurrentContext();
72 if (frame && render_view) {
73 std::string webstore_item_id;
74 std::string error;
75 if (GetWebstoreItemIdFromFrame(frame, &webstore_item_id, &error)) {
76 ExtensionHelper* helper = ExtensionHelper::Get(render_view);
Aaron Boodman 2011/08/17 04:53:03 I don't see this method defined on ExtensionHelper
Mihai Parparita -not on Chrome 2011/08/17 23:00:16 chrome_app_bindings.cc and extension_process_bindi
Aaron Boodman 2011/08/17 23:15:41 Um, ok. I think this changed since I last saw it.
77 helper->InlineWebstoreInstall(webstore_item_id);
78 } else {
79 v8::ThrowException(v8::String::New(error.c_str()));
80 }
81 }
82
83 return v8::Undefined();
84 }
85
86 private:
87 // Extracts a Web Store item ID from a <link rel="chrome-webstore-item"
88 // href="https://chrome.google.com/webstore/detail/id"> node found in the
89 // frame. On success, true will be returned and the |webstore_item_id|
90 // parameter will be populated with the ID. On failure, false will be returned
91 // and |error| will be populated with the error.
92 static bool GetWebstoreItemIdFromFrame(
93 WebFrame* frame, std::string* webstore_item_id, std::string* error) {
94 if (frame != frame->top()) {
95 *error = kNotInTopFrameError;
96 return false;
97 }
98
99 if (!frame->isProcessingUserGesture()) {
100 *error = kNotUserGestureError;
101 return false;
102 }
103
104 WebDocument document = frame->document();
105 if (document.isNull()) {
106 *error = kNoWebstoreItemLinkFoundError;
107 return false;
108 }
109
110 WebElement head = document.head();
111 if (head.isNull()) {
112 *error = kNoWebstoreItemLinkFoundError;
113 return false;
114 }
115
116 GURL webstore_base_url =
117 GURL(::Extension::ChromeStoreItemDetailURLPrefix());
118 WebNodeList children = head.childNodes();
119 for (unsigned i = 0; i < children.length(); ++i) {
120 WebNode child = children.item(i);
121 if (!child.isElementNode())
122 continue;
123 WebElement elem = child.to<WebElement>();
124
125 if (!elem.hasTagName("link") || !elem.hasAttribute("rel") ||
126 !elem.hasAttribute("href"))
127 continue;
128
129 std::string rel = elem.getAttribute("rel").utf8();
130 if (!LowerCaseEqualsASCII(rel, kWebstoreLinkRelation))
131 continue;
132
133 std::string webstore_url_string(elem.getAttribute("href").utf8());
134 GURL webstore_url = GURL(webstore_url_string);
135 if (!webstore_url.is_valid()) {
136 *error = kInvalidWebstoreItemUrlError;
137 return false;
138 }
139
140 if (webstore_url.scheme() != webstore_base_url.scheme() ||
141 webstore_url.host() != webstore_base_url.host() ||
142 !StartsWithASCII(
143 webstore_url.path(), webstore_base_url.path(), true)) {
144 *error = kInvalidWebstoreItemUrlError;
145 return false;
146 }
147
148 std::string candidate_webstore_item_id = webstore_url.path().substr(
149 webstore_base_url.path().length());
150 std::string reconstructed_webstore_item_url_string =
151 ::Extension::ChromeStoreItemDetailURLPrefix() +
152 candidate_webstore_item_id;
153 if (reconstructed_webstore_item_url_string != webstore_url_string) {
154 *error = kInvalidWebstoreItemUrlError;
155 return false;
156 }
157
158 *webstore_item_id = candidate_webstore_item_id;
159 return true;
160 }
161
162 *error = kNoWebstoreItemLinkFoundError;
163 return false;
164 }
165 };
166
167 v8::Extension* ChromeWebstoreExtension::Get() {
168 return new ChromeWebstoreExtensionWrapper();
169 }
170
171 } // namespace extensions_v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698