Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / components / plugins / renderer / mobile_youtube_plugin.cc
1 // Copyright 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 "components/plugins/renderer/mobile_youtube_plugin.h"
6
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/strings/string_piece.h"
10 #include "base/strings/string_util.h"
11 #include "base/values.h"
12 #include "content/public/common/content_constants.h"
13 #include "content/public/renderer/render_frame.h"
14 #include "gin/handle.h"
15 #include "gin/object_template_builder.h"
16 #include "third_party/WebKit/public/web/WebFrame.h"
17 #include "third_party/WebKit/public/web/WebKit.h"
18 #include "ui/base/webui/jstemplate_builder.h"
19
20 using blink::WebFrame;
21 using blink::WebPlugin;
22 using blink::WebURLRequest;
23
24 const char* const kSlashVSlash = "/v/";
25 const char* const kSlashESlash = "/e/";
26
27 namespace {
28
29 std::string GetYoutubeVideoId(const blink::WebPluginParams& params) {
30   GURL url(params.url);
31   std::string video_id = url.path().substr(strlen(kSlashVSlash));
32
33   // Extract just the video id
34   size_t video_id_end = video_id.find('&');
35   if (video_id_end != std::string::npos)
36     video_id = video_id.substr(0, video_id_end);
37   return video_id;
38 }
39
40 std::string HtmlData(const blink::WebPluginParams& params,
41                      base::StringPiece template_html) {
42   base::DictionaryValue values;
43   values.SetString("video_id", GetYoutubeVideoId(params));
44   return webui::GetI18nTemplateHtml(template_html, &values);
45 }
46
47 bool IsValidYouTubeVideo(const std::string& path) {
48   unsigned len = strlen(kSlashVSlash);
49
50   // check for more than just /v/ or /e/.
51   if (path.length() <= len)
52     return false;
53
54   std::string str = base::StringToLowerASCII(path);
55   // Youtube flash url can start with /v/ or /e/.
56   if (strncmp(str.data(), kSlashVSlash, len) != 0 &&
57       strncmp(str.data(), kSlashESlash, len) != 0)
58     return false;
59
60   // Start after /v/
61   for (unsigned i = len; i < path.length(); i++) {
62     char c = str[i];
63     if (isalpha(c) || isdigit(c) || c == '_' || c == '-')
64       continue;
65     // The url can have more parameters such as &hl=en after the video id.
66     // Once we start seeing extra parameters we can return true.
67     return c == '&' && i > len;
68   }
69   return true;
70 }
71
72 }  // namespace
73
74 namespace plugins {
75
76 MobileYouTubePlugin::MobileYouTubePlugin(content::RenderFrame* render_frame,
77                                          blink::WebLocalFrame* frame,
78                                          const blink::WebPluginParams& params,
79                                          base::StringPiece& template_html,
80                                          GURL placeholderDataUrl)
81     : PluginPlaceholder(render_frame,
82                         frame,
83                         params,
84                         HtmlData(params, template_html),
85                         placeholderDataUrl) {}
86
87 MobileYouTubePlugin::~MobileYouTubePlugin() {}
88
89 // static
90 bool MobileYouTubePlugin::IsYouTubeURL(const GURL& url,
91                                        const std::string& mime_type) {
92   std::string host = url.host();
93   bool is_youtube = EndsWith(host, "youtube.com", true) ||
94                     EndsWith(host, "youtube-nocookie.com", true);
95
96   return is_youtube && IsValidYouTubeVideo(url.path()) &&
97          LowerCaseEqualsASCII(mime_type, content::kFlashPluginSwfMimeType);
98 }
99
100 void MobileYouTubePlugin::OpenYoutubeUrlCallback() {
101   std::string youtube("vnd.youtube:");
102   GURL url(youtube.append(GetYoutubeVideoId(GetPluginParams())));
103   WebURLRequest request;
104   request.initialize();
105   request.setURL(url);
106   render_frame()->LoadURLExternally(
107       GetFrame(), request, blink::WebNavigationPolicyNewForegroundTab);
108 }
109
110 void MobileYouTubePlugin::BindWebFrame(WebFrame* frame) {
111   v8::Isolate* isolate = blink::mainThreadIsolate();
112   v8::HandleScope handle_scope(isolate);
113   v8::Local<v8::Context> context = frame->mainWorldScriptContext();
114   DCHECK(!context.IsEmpty());
115
116   v8::Context::Scope context_scope(context);
117   v8::Local<v8::Object> global = context->Global();
118   global->Set(gin::StringToV8(isolate, "plugin"),
119               gin::CreateHandle(isolate, this).ToV8());
120 }
121
122 gin::ObjectTemplateBuilder MobileYouTubePlugin::GetObjectTemplateBuilder(
123     v8::Isolate* isolate) {
124   return PluginPlaceholder::GetObjectTemplateBuilder(isolate)
125     .SetMethod("openYoutubeURL", &MobileYouTubePlugin::OpenYoutubeUrlCallback);
126 }
127
128 }  // namespace plugins