OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/extensions/api/tabs/tabs.h" | 5 #include "chrome/browser/extensions/api/tabs/tabs.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <limits> | 8 #include <limits> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
45 #include "chrome/browser/ui/panels/panel_manager.h" | 45 #include "chrome/browser/ui/panels/panel_manager.h" |
46 #include "chrome/browser/ui/snapshot_tab_helper.h" | 46 #include "chrome/browser/ui/snapshot_tab_helper.h" |
47 #include "chrome/browser/ui/tab_contents/tab_contents.h" | 47 #include "chrome/browser/ui/tab_contents/tab_contents.h" |
48 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 48 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
49 #include "chrome/browser/ui/window_sizer/window_sizer.h" | 49 #include "chrome/browser/ui/window_sizer/window_sizer.h" |
50 #include "chrome/browser/web_applications/web_app.h" | 50 #include "chrome/browser/web_applications/web_app.h" |
51 #include "chrome/common/chrome_notification_types.h" | 51 #include "chrome/common/chrome_notification_types.h" |
52 #include "chrome/common/chrome_switches.h" | 52 #include "chrome/common/chrome_switches.h" |
53 #include "chrome/common/extensions/api/windows.h" | 53 #include "chrome/common/extensions/api/windows.h" |
54 #include "chrome/common/extensions/extension.h" | 54 #include "chrome/common/extensions/extension.h" |
55 #include "chrome/common/extensions/extension_error_utils.h" | |
56 #include "chrome/common/extensions/extension_manifest_constants.h" | 55 #include "chrome/common/extensions/extension_manifest_constants.h" |
57 #include "chrome/common/extensions/extension_messages.h" | 56 #include "chrome/common/extensions/extension_messages.h" |
58 #include "chrome/common/extensions/user_script.h" | 57 #include "chrome/common/extensions/user_script.h" |
59 #include "chrome/common/pref_names.h" | 58 #include "chrome/common/pref_names.h" |
60 #include "chrome/common/url_constants.h" | 59 #include "chrome/common/url_constants.h" |
61 #include "content/public/browser/navigation_controller.h" | 60 #include "content/public/browser/navigation_controller.h" |
62 #include "content/public/browser/navigation_entry.h" | 61 #include "content/public/browser/navigation_entry.h" |
63 #include "content/public/browser/notification_details.h" | 62 #include "content/public/browser/notification_details.h" |
64 #include "content/public/browser/notification_source.h" | 63 #include "content/public/browser/notification_source.h" |
65 #include "content/public/browser/render_view_host.h" | 64 #include "content/public/browser/render_view_host.h" |
66 #include "content/public/browser/render_widget_host_view.h" | 65 #include "content/public/browser/render_widget_host_view.h" |
67 #include "content/public/browser/web_contents.h" | 66 #include "content/public/browser/web_contents.h" |
68 #include "content/public/browser/web_contents_view.h" | 67 #include "content/public/browser/web_contents_view.h" |
69 #include "content/public/common/url_constants.h" | 68 #include "content/public/common/url_constants.h" |
70 #include "extensions/common/constants.h" | 69 #include "extensions/common/constants.h" |
| 70 #include "extensions/common/extension_error_utils.h" |
71 #include "skia/ext/image_operations.h" | 71 #include "skia/ext/image_operations.h" |
72 #include "skia/ext/platform_canvas.h" | 72 #include "skia/ext/platform_canvas.h" |
73 #include "third_party/skia/include/core/SkBitmap.h" | 73 #include "third_party/skia/include/core/SkBitmap.h" |
74 #include "ui/base/ui_base_types.h" | 74 #include "ui/base/ui_base_types.h" |
75 #include "ui/gfx/codec/jpeg_codec.h" | 75 #include "ui/gfx/codec/jpeg_codec.h" |
76 #include "ui/gfx/codec/png_codec.h" | 76 #include "ui/gfx/codec/png_codec.h" |
77 | 77 |
78 #if defined(OS_WIN) | 78 #if defined(OS_WIN) |
79 #include "base/win/metro.h" | 79 #include "base/win/metro.h" |
80 #endif // OS_WIN | 80 #endif // OS_WIN |
81 | 81 |
82 namespace Get = extensions::api::windows::Get; | 82 namespace Get = extensions::api::windows::Get; |
83 namespace GetAll = extensions::api::windows::GetAll; | 83 namespace GetAll = extensions::api::windows::GetAll; |
84 namespace GetCurrent = extensions::api::windows::GetCurrent; | 84 namespace GetCurrent = extensions::api::windows::GetCurrent; |
85 namespace GetLastFocused = extensions::api::windows::GetLastFocused; | 85 namespace GetLastFocused = extensions::api::windows::GetLastFocused; |
86 namespace errors = extension_manifest_errors; | 86 namespace errors = extension_manifest_errors; |
87 namespace keys = extensions::tabs_constants; | 87 namespace keys = extensions::tabs_constants; |
88 | 88 |
89 using content::NavigationController; | 89 using content::NavigationController; |
90 using content::NavigationEntry; | 90 using content::NavigationEntry; |
91 using content::OpenURLParams; | 91 using content::OpenURLParams; |
92 using content::Referrer; | 92 using content::Referrer; |
93 using content::RenderViewHost; | 93 using content::RenderViewHost; |
94 using content::WebContents; | 94 using content::WebContents; |
| 95 using extensions::ErrorUtils; |
95 using extensions::ScriptExecutor; | 96 using extensions::ScriptExecutor; |
96 using extensions::WindowController; | 97 using extensions::WindowController; |
97 using extensions::WindowControllerList; | 98 using extensions::WindowControllerList; |
98 | 99 |
99 const int CaptureVisibleTabFunction::kDefaultQuality = 90; | 100 const int CaptureVisibleTabFunction::kDefaultQuality = 90; |
100 | 101 |
101 namespace { | 102 namespace { |
102 | 103 |
103 // |error_message| can optionally be passed in a will be set with an appropriate | 104 // |error_message| can optionally be passed in a will be set with an appropriate |
104 // message if the window cannot be found by id. | 105 // message if the window cannot be found by id. |
105 Browser* GetBrowserInProfileWithId(Profile* profile, | 106 Browser* GetBrowserInProfileWithId(Profile* profile, |
106 const int window_id, | 107 const int window_id, |
107 bool include_incognito, | 108 bool include_incognito, |
108 std::string* error_message) { | 109 std::string* error_message) { |
109 Profile* incognito_profile = | 110 Profile* incognito_profile = |
110 include_incognito && profile->HasOffTheRecordProfile() ? | 111 include_incognito && profile->HasOffTheRecordProfile() ? |
111 profile->GetOffTheRecordProfile() : NULL; | 112 profile->GetOffTheRecordProfile() : NULL; |
112 for (BrowserList::const_iterator browser = BrowserList::begin(); | 113 for (BrowserList::const_iterator browser = BrowserList::begin(); |
113 browser != BrowserList::end(); ++browser) { | 114 browser != BrowserList::end(); ++browser) { |
114 if (((*browser)->profile() == profile || | 115 if (((*browser)->profile() == profile || |
115 (*browser)->profile() == incognito_profile) && | 116 (*browser)->profile() == incognito_profile) && |
116 ExtensionTabUtil::GetWindowId(*browser) == window_id && | 117 ExtensionTabUtil::GetWindowId(*browser) == window_id && |
117 ((*browser)->window())) | 118 ((*browser)->window())) |
118 return *browser; | 119 return *browser; |
119 } | 120 } |
120 | 121 |
121 if (error_message) | 122 if (error_message) |
122 *error_message = ExtensionErrorUtils::FormatErrorMessage( | 123 *error_message = ErrorUtils::FormatErrorMessage( |
123 keys::kWindowNotFoundError, base::IntToString(window_id)); | 124 keys::kWindowNotFoundError, base::IntToString(window_id)); |
124 | 125 |
125 return NULL; | 126 return NULL; |
126 } | 127 } |
127 | 128 |
128 bool GetBrowserFromWindowID( | 129 bool GetBrowserFromWindowID( |
129 UIThreadExtensionFunction* function, int window_id, Browser** browser) { | 130 UIThreadExtensionFunction* function, int window_id, Browser** browser) { |
130 if (window_id == extension_misc::kCurrentWindowId) { | 131 if (window_id == extension_misc::kCurrentWindowId) { |
131 *browser = function->GetCurrentBrowser(); | 132 *browser = function->GetCurrentBrowser(); |
132 if (!(*browser) || !(*browser)->window()) { | 133 if (!(*browser) || !(*browser)->window()) { |
(...skipping 27 matching lines...) Expand all Loading... |
160 CurrentWindowForFunction(function); | 161 CurrentWindowForFunction(function); |
161 } | 162 } |
162 if (!(*controller)) { | 163 if (!(*controller)) { |
163 function->SetError(keys::kNoCurrentWindowError); | 164 function->SetError(keys::kNoCurrentWindowError); |
164 return false; | 165 return false; |
165 } | 166 } |
166 } else { | 167 } else { |
167 *controller = WindowControllerList::GetInstance()-> | 168 *controller = WindowControllerList::GetInstance()-> |
168 FindWindowForFunctionById(function, window_id); | 169 FindWindowForFunctionById(function, window_id); |
169 if (!(*controller)) { | 170 if (!(*controller)) { |
170 function->SetError(ExtensionErrorUtils::FormatErrorMessage( | 171 function->SetError(ErrorUtils::FormatErrorMessage( |
171 keys::kWindowNotFoundError, base::IntToString(window_id))); | 172 keys::kWindowNotFoundError, base::IntToString(window_id))); |
172 return false; | 173 return false; |
173 } | 174 } |
174 } | 175 } |
175 return true; | 176 return true; |
176 } | 177 } |
177 | 178 |
178 // |error_message| can optionally be passed in and will be set with an | 179 // |error_message| can optionally be passed in and will be set with an |
179 // appropriate message if the tab cannot be found by id. | 180 // appropriate message if the tab cannot be found by id. |
180 bool GetTabById(int tab_id, | 181 bool GetTabById(int tab_id, |
181 Profile* profile, | 182 Profile* profile, |
182 bool include_incognito, | 183 bool include_incognito, |
183 Browser** browser, | 184 Browser** browser, |
184 TabStripModel** tab_strip, | 185 TabStripModel** tab_strip, |
185 content::WebContents** contents, | 186 content::WebContents** contents, |
186 int* tab_index, | 187 int* tab_index, |
187 std::string* error_message) { | 188 std::string* error_message) { |
188 if (ExtensionTabUtil::GetTabById(tab_id, profile, include_incognito, | 189 if (ExtensionTabUtil::GetTabById(tab_id, profile, include_incognito, |
189 browser, tab_strip, contents, tab_index)) | 190 browser, tab_strip, contents, tab_index)) |
190 return true; | 191 return true; |
191 | 192 |
192 if (error_message) | 193 if (error_message) |
193 *error_message = ExtensionErrorUtils::FormatErrorMessage( | 194 *error_message = ErrorUtils::FormatErrorMessage( |
194 keys::kTabNotFoundError, base::IntToString(tab_id)); | 195 keys::kTabNotFoundError, base::IntToString(tab_id)); |
195 | 196 |
196 return false; | 197 return false; |
197 } | 198 } |
198 | 199 |
199 // A three state enum to distinguish between when a boolean query argument is | 200 // A three state enum to distinguish between when a boolean query argument is |
200 // set or not. | 201 // set or not. |
201 enum QueryArg { | 202 enum QueryArg { |
202 NOT_SET = -1, | 203 NOT_SET = -1, |
203 MATCH_FALSE, | 204 MATCH_FALSE, |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
372 for (size_t i = 0; i < urls->size();) { | 373 for (size_t i = 0; i < urls->size();) { |
373 if (chrome::IsURLAllowedInIncognito((*urls)[i], profile())) { | 374 if (chrome::IsURLAllowedInIncognito((*urls)[i], profile())) { |
374 i++; | 375 i++; |
375 } else { | 376 } else { |
376 if (first_url_erased.empty()) | 377 if (first_url_erased.empty()) |
377 first_url_erased = (*urls)[i].spec(); | 378 first_url_erased = (*urls)[i].spec(); |
378 urls->erase(urls->begin() + i); | 379 urls->erase(urls->begin() + i); |
379 } | 380 } |
380 } | 381 } |
381 if (urls->empty() && !first_url_erased.empty()) { | 382 if (urls->empty() && !first_url_erased.empty()) { |
382 error_ = ExtensionErrorUtils::FormatErrorMessage( | 383 error_ = ErrorUtils::FormatErrorMessage( |
383 keys::kURLsNotAllowedInIncognitoError, first_url_erased); | 384 keys::kURLsNotAllowedInIncognitoError, first_url_erased); |
384 *is_error = true; | 385 *is_error = true; |
385 return false; | 386 return false; |
386 } | 387 } |
387 } | 388 } |
388 return incognito; | 389 return incognito; |
389 } | 390 } |
390 | 391 |
391 bool CreateWindowFunction::RunImpl() { | 392 bool CreateWindowFunction::RunImpl() { |
392 DictionaryValue* args = NULL; | 393 DictionaryValue* args = NULL; |
(...skipping 23 matching lines...) Expand all Loading... |
416 url_strings.push_back(url_string); | 417 url_strings.push_back(url_string); |
417 } | 418 } |
418 } | 419 } |
419 | 420 |
420 // Second, resolve, validate and convert them to GURLs. | 421 // Second, resolve, validate and convert them to GURLs. |
421 for (std::vector<std::string>::iterator i = url_strings.begin(); | 422 for (std::vector<std::string>::iterator i = url_strings.begin(); |
422 i != url_strings.end(); ++i) { | 423 i != url_strings.end(); ++i) { |
423 GURL url = ExtensionTabUtil::ResolvePossiblyRelativeURL( | 424 GURL url = ExtensionTabUtil::ResolvePossiblyRelativeURL( |
424 *i, GetExtension()); | 425 *i, GetExtension()); |
425 if (!url.is_valid()) { | 426 if (!url.is_valid()) { |
426 error_ = ExtensionErrorUtils::FormatErrorMessage( | 427 error_ = ErrorUtils::FormatErrorMessage( |
427 keys::kInvalidUrlError, *i); | 428 keys::kInvalidUrlError, *i); |
428 return false; | 429 return false; |
429 } | 430 } |
430 // Don't let the extension crash the browser or renderers. | 431 // Don't let the extension crash the browser or renderers. |
431 if (ExtensionTabUtil::IsCrashURL(url)) { | 432 if (ExtensionTabUtil::IsCrashURL(url)) { |
432 error_ = keys::kNoCrashBrowserError; | 433 error_ = keys::kNoCrashBrowserError; |
433 return false; | 434 return false; |
434 } | 435 } |
435 urls.push_back(url); | 436 urls.push_back(url); |
436 } | 437 } |
437 } | 438 } |
438 } | 439 } |
439 | 440 |
440 // Look for optional tab id. | 441 // Look for optional tab id. |
441 if (args) { | 442 if (args) { |
442 int tab_id = -1; | 443 int tab_id = -1; |
443 if (args->HasKey(keys::kTabIdKey)) { | 444 if (args->HasKey(keys::kTabIdKey)) { |
444 EXTENSION_FUNCTION_VALIDATE(args->GetInteger(keys::kTabIdKey, &tab_id)); | 445 EXTENSION_FUNCTION_VALIDATE(args->GetInteger(keys::kTabIdKey, &tab_id)); |
445 | 446 |
446 // Find the tab and detach it from the original window. | 447 // Find the tab and detach it from the original window. |
447 TabStripModel* source_tab_strip = NULL; | 448 TabStripModel* source_tab_strip = NULL; |
448 int tab_index = -1; | 449 int tab_index = -1; |
449 if (!GetTabById(tab_id, profile(), include_incognito(), | 450 if (!GetTabById(tab_id, profile(), include_incognito(), |
450 NULL, &source_tab_strip, | 451 NULL, &source_tab_strip, |
451 NULL, &tab_index, &error_)) | 452 NULL, &tab_index, &error_)) |
452 return false; | 453 return false; |
453 contents = source_tab_strip->DetachTabContentsAt(tab_index); | 454 contents = source_tab_strip->DetachTabContentsAt(tab_index); |
454 if (!contents) { | 455 if (!contents) { |
455 error_ = ExtensionErrorUtils::FormatErrorMessage( | 456 error_ = ErrorUtils::FormatErrorMessage( |
456 keys::kTabNotFoundError, base::IntToString(tab_id)); | 457 keys::kTabNotFoundError, base::IntToString(tab_id)); |
457 return false; | 458 return false; |
458 } | 459 } |
459 } | 460 } |
460 } | 461 } |
461 | 462 |
462 Profile* window_profile = profile(); | 463 Profile* window_profile = profile(); |
463 Browser::Type window_type = Browser::TYPE_TABBED; | 464 Browser::Type window_type = Browser::TYPE_TABBED; |
464 | 465 |
465 // panel_create_mode only applies if window is TYPE_PANEL. | 466 // panel_create_mode only applies if window is TYPE_PANEL. |
(...skipping 553 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1019 // -favIconUrl | 1020 // -favIconUrl |
1020 | 1021 |
1021 std::string url_string; | 1022 std::string url_string; |
1022 GURL url; | 1023 GURL url; |
1023 if (args->HasKey(keys::kUrlKey)) { | 1024 if (args->HasKey(keys::kUrlKey)) { |
1024 EXTENSION_FUNCTION_VALIDATE(args->GetString(keys::kUrlKey, | 1025 EXTENSION_FUNCTION_VALIDATE(args->GetString(keys::kUrlKey, |
1025 &url_string)); | 1026 &url_string)); |
1026 url = ExtensionTabUtil::ResolvePossiblyRelativeURL(url_string, | 1027 url = ExtensionTabUtil::ResolvePossiblyRelativeURL(url_string, |
1027 GetExtension()); | 1028 GetExtension()); |
1028 if (!url.is_valid()) { | 1029 if (!url.is_valid()) { |
1029 error_ = ExtensionErrorUtils::FormatErrorMessage(keys::kInvalidUrlError, | 1030 error_ = ErrorUtils::FormatErrorMessage(keys::kInvalidUrlError, |
1030 url_string); | 1031 url_string); |
1031 return false; | 1032 return false; |
1032 } | 1033 } |
1033 } | 1034 } |
1034 | 1035 |
1035 // Don't let extensions crash the browser or renderers. | 1036 // Don't let extensions crash the browser or renderers. |
1036 if (ExtensionTabUtil::IsCrashURL(url)) { | 1037 if (ExtensionTabUtil::IsCrashURL(url)) { |
1037 error_ = keys::kNoCrashBrowserError; | 1038 error_ = keys::kNoCrashBrowserError; |
1038 return false; | 1039 return false; |
1039 } | 1040 } |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1187 std::vector<int> tab_indices; | 1188 std::vector<int> tab_indices; |
1188 EXTENSION_FUNCTION_VALIDATE(extensions::ReadOneOrMoreIntegers( | 1189 EXTENSION_FUNCTION_VALIDATE(extensions::ReadOneOrMoreIntegers( |
1189 tab_value, &tab_indices)); | 1190 tab_value, &tab_indices)); |
1190 | 1191 |
1191 // Create a new selection model as we read the list of tab indices. | 1192 // Create a new selection model as we read the list of tab indices. |
1192 for (size_t i = 0; i < tab_indices.size(); ++i) { | 1193 for (size_t i = 0; i < tab_indices.size(); ++i) { |
1193 int index = tab_indices[i]; | 1194 int index = tab_indices[i]; |
1194 | 1195 |
1195 // Make sure the index is in range. | 1196 // Make sure the index is in range. |
1196 if (!tabstrip->ContainsIndex(index)) { | 1197 if (!tabstrip->ContainsIndex(index)) { |
1197 error_ = ExtensionErrorUtils::FormatErrorMessage( | 1198 error_ = ErrorUtils::FormatErrorMessage( |
1198 keys::kTabIndexNotFoundError, base::IntToString(index)); | 1199 keys::kTabIndexNotFoundError, base::IntToString(index)); |
1199 return false; | 1200 return false; |
1200 } | 1201 } |
1201 | 1202 |
1202 // By default, we make the first tab in the list active. | 1203 // By default, we make the first tab in the list active. |
1203 if (active_index == -1) | 1204 if (active_index == -1) |
1204 active_index = index; | 1205 active_index = index; |
1205 | 1206 |
1206 selection.AddIndexToSelection(index); | 1207 selection.AddIndexToSelection(index); |
1207 } | 1208 } |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1333 if (!update_props->HasKey(keys::kUrlKey)) | 1334 if (!update_props->HasKey(keys::kUrlKey)) |
1334 return true; | 1335 return true; |
1335 | 1336 |
1336 std::string url_string; | 1337 std::string url_string; |
1337 EXTENSION_FUNCTION_VALIDATE(update_props->GetString( | 1338 EXTENSION_FUNCTION_VALIDATE(update_props->GetString( |
1338 keys::kUrlKey, &url_string)); | 1339 keys::kUrlKey, &url_string)); |
1339 GURL url = ExtensionTabUtil::ResolvePossiblyRelativeURL( | 1340 GURL url = ExtensionTabUtil::ResolvePossiblyRelativeURL( |
1340 url_string, GetExtension()); | 1341 url_string, GetExtension()); |
1341 | 1342 |
1342 if (!url.is_valid()) { | 1343 if (!url.is_valid()) { |
1343 error_ = ExtensionErrorUtils::FormatErrorMessage( | 1344 error_ = ErrorUtils::FormatErrorMessage( |
1344 keys::kInvalidUrlError, url_string); | 1345 keys::kInvalidUrlError, url_string); |
1345 return false; | 1346 return false; |
1346 } | 1347 } |
1347 | 1348 |
1348 // Don't let the extension crash the browser or renderers. | 1349 // Don't let the extension crash the browser or renderers. |
1349 if (ExtensionTabUtil::IsCrashURL(url)) { | 1350 if (ExtensionTabUtil::IsCrashURL(url)) { |
1350 error_ = keys::kNoCrashBrowserError; | 1351 error_ = keys::kNoCrashBrowserError; |
1351 return false; | 1352 return false; |
1352 } | 1353 } |
1353 | 1354 |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1464 return false; | 1465 return false; |
1465 } | 1466 } |
1466 | 1467 |
1467 // If windowId is different from the current window, move between windows. | 1468 // If windowId is different from the current window, move between windows. |
1468 if (ExtensionTabUtil::GetWindowId(target_browser) != | 1469 if (ExtensionTabUtil::GetWindowId(target_browser) != |
1469 ExtensionTabUtil::GetWindowId(source_browser)) { | 1470 ExtensionTabUtil::GetWindowId(source_browser)) { |
1470 TabStripModel* target_tab_strip = target_browser->tab_strip_model(); | 1471 TabStripModel* target_tab_strip = target_browser->tab_strip_model(); |
1471 TabContents* tab_contents = | 1472 TabContents* tab_contents = |
1472 source_tab_strip->DetachTabContentsAt(tab_index); | 1473 source_tab_strip->DetachTabContentsAt(tab_index); |
1473 if (!tab_contents) { | 1474 if (!tab_contents) { |
1474 error_ = ExtensionErrorUtils::FormatErrorMessage( | 1475 error_ = ErrorUtils::FormatErrorMessage( |
1475 keys::kTabNotFoundError, base::IntToString(tab_ids[i])); | 1476 keys::kTabNotFoundError, base::IntToString(tab_ids[i])); |
1476 return false; | 1477 return false; |
1477 } | 1478 } |
1478 | 1479 |
1479 // Clamp move location to the last position. | 1480 // Clamp move location to the last position. |
1480 // This is ">" because it can append to a new index position. | 1481 // This is ">" because it can append to a new index position. |
1481 // -1 means set the move location to the last position. | 1482 // -1 means set the move location to the last position. |
1482 if (new_index > target_tab_strip->count() || new_index < 0) | 1483 if (new_index > target_tab_strip->count() || new_index < 0) |
1483 new_index = target_tab_strip->count(); | 1484 new_index = target_tab_strip->count(); |
1484 | 1485 |
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1867 // called for every API call the extension made. | 1868 // called for every API call the extension made. |
1868 GotLanguage(language); | 1869 GotLanguage(language); |
1869 } | 1870 } |
1870 | 1871 |
1871 void DetectTabLanguageFunction::GotLanguage(const std::string& language) { | 1872 void DetectTabLanguageFunction::GotLanguage(const std::string& language) { |
1872 SetResult(Value::CreateStringValue(language.c_str())); | 1873 SetResult(Value::CreateStringValue(language.c_str())); |
1873 SendResponse(true); | 1874 SendResponse(true); |
1874 | 1875 |
1875 Release(); // Balanced in Run() | 1876 Release(); // Balanced in Run() |
1876 } | 1877 } |
OLD | NEW |