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/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 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
373 for (size_t i = 0; i < urls->size();) { | 374 for (size_t i = 0; i < urls->size();) { |
374 if (chrome::IsURLAllowedInIncognito((*urls)[i], profile())) { | 375 if (chrome::IsURLAllowedInIncognito((*urls)[i], profile())) { |
375 i++; | 376 i++; |
376 } else { | 377 } else { |
377 if (first_url_erased.empty()) | 378 if (first_url_erased.empty()) |
378 first_url_erased = (*urls)[i].spec(); | 379 first_url_erased = (*urls)[i].spec(); |
379 urls->erase(urls->begin() + i); | 380 urls->erase(urls->begin() + i); |
380 } | 381 } |
381 } | 382 } |
382 if (urls->empty() && !first_url_erased.empty()) { | 383 if (urls->empty() && !first_url_erased.empty()) { |
383 error_ = ExtensionErrorUtils::FormatErrorMessage( | 384 error_ = ErrorUtils::FormatErrorMessage( |
384 keys::kURLsNotAllowedInIncognitoError, first_url_erased); | 385 keys::kURLsNotAllowedInIncognitoError, first_url_erased); |
385 *is_error = true; | 386 *is_error = true; |
386 return false; | 387 return false; |
387 } | 388 } |
388 } | 389 } |
389 return incognito; | 390 return incognito; |
390 } | 391 } |
391 | 392 |
392 bool CreateWindowFunction::RunImpl() { | 393 bool CreateWindowFunction::RunImpl() { |
393 DictionaryValue* args = NULL; | 394 DictionaryValue* args = NULL; |
(...skipping 23 matching lines...) Expand all Loading... |
417 url_strings.push_back(url_string); | 418 url_strings.push_back(url_string); |
418 } | 419 } |
419 } | 420 } |
420 | 421 |
421 // Second, resolve, validate and convert them to GURLs. | 422 // Second, resolve, validate and convert them to GURLs. |
422 for (std::vector<std::string>::iterator i = url_strings.begin(); | 423 for (std::vector<std::string>::iterator i = url_strings.begin(); |
423 i != url_strings.end(); ++i) { | 424 i != url_strings.end(); ++i) { |
424 GURL url = ExtensionTabUtil::ResolvePossiblyRelativeURL( | 425 GURL url = ExtensionTabUtil::ResolvePossiblyRelativeURL( |
425 *i, GetExtension()); | 426 *i, GetExtension()); |
426 if (!url.is_valid()) { | 427 if (!url.is_valid()) { |
427 error_ = ExtensionErrorUtils::FormatErrorMessage( | 428 error_ = ErrorUtils::FormatErrorMessage( |
428 keys::kInvalidUrlError, *i); | 429 keys::kInvalidUrlError, *i); |
429 return false; | 430 return false; |
430 } | 431 } |
431 // Don't let the extension crash the browser or renderers. | 432 // Don't let the extension crash the browser or renderers. |
432 if (ExtensionTabUtil::IsCrashURL(url)) { | 433 if (ExtensionTabUtil::IsCrashURL(url)) { |
433 error_ = keys::kNoCrashBrowserError; | 434 error_ = keys::kNoCrashBrowserError; |
434 return false; | 435 return false; |
435 } | 436 } |
436 urls.push_back(url); | 437 urls.push_back(url); |
437 } | 438 } |
438 } | 439 } |
439 } | 440 } |
440 | 441 |
441 // Look for optional tab id. | 442 // Look for optional tab id. |
442 if (args) { | 443 if (args) { |
443 int tab_id = -1; | 444 int tab_id = -1; |
444 if (args->HasKey(keys::kTabIdKey)) { | 445 if (args->HasKey(keys::kTabIdKey)) { |
445 EXTENSION_FUNCTION_VALIDATE(args->GetInteger(keys::kTabIdKey, &tab_id)); | 446 EXTENSION_FUNCTION_VALIDATE(args->GetInteger(keys::kTabIdKey, &tab_id)); |
446 | 447 |
447 // Find the tab and detach it from the original window. | 448 // Find the tab and detach it from the original window. |
448 TabStripModel* source_tab_strip = NULL; | 449 TabStripModel* source_tab_strip = NULL; |
449 int tab_index = -1; | 450 int tab_index = -1; |
450 if (!GetTabById(tab_id, profile(), include_incognito(), | 451 if (!GetTabById(tab_id, profile(), include_incognito(), |
451 NULL, &source_tab_strip, | 452 NULL, &source_tab_strip, |
452 NULL, &tab_index, &error_)) | 453 NULL, &tab_index, &error_)) |
453 return false; | 454 return false; |
454 contents = source_tab_strip->DetachTabContentsAt(tab_index); | 455 contents = source_tab_strip->DetachTabContentsAt(tab_index); |
455 if (!contents) { | 456 if (!contents) { |
456 error_ = ExtensionErrorUtils::FormatErrorMessage( | 457 error_ = ErrorUtils::FormatErrorMessage( |
457 keys::kTabNotFoundError, base::IntToString(tab_id)); | 458 keys::kTabNotFoundError, base::IntToString(tab_id)); |
458 return false; | 459 return false; |
459 } | 460 } |
460 } | 461 } |
461 } | 462 } |
462 | 463 |
463 Profile* window_profile = profile(); | 464 Profile* window_profile = profile(); |
464 Browser::Type window_type = Browser::TYPE_TABBED; | 465 Browser::Type window_type = Browser::TYPE_TABBED; |
465 | 466 |
466 // panel_create_mode only applies if window is TYPE_PANEL. | 467 // panel_create_mode only applies if window is TYPE_PANEL. |
(...skipping 553 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1020 // -favIconUrl | 1021 // -favIconUrl |
1021 | 1022 |
1022 std::string url_string; | 1023 std::string url_string; |
1023 GURL url; | 1024 GURL url; |
1024 if (args->HasKey(keys::kUrlKey)) { | 1025 if (args->HasKey(keys::kUrlKey)) { |
1025 EXTENSION_FUNCTION_VALIDATE(args->GetString(keys::kUrlKey, | 1026 EXTENSION_FUNCTION_VALIDATE(args->GetString(keys::kUrlKey, |
1026 &url_string)); | 1027 &url_string)); |
1027 url = ExtensionTabUtil::ResolvePossiblyRelativeURL(url_string, | 1028 url = ExtensionTabUtil::ResolvePossiblyRelativeURL(url_string, |
1028 GetExtension()); | 1029 GetExtension()); |
1029 if (!url.is_valid()) { | 1030 if (!url.is_valid()) { |
1030 error_ = ExtensionErrorUtils::FormatErrorMessage(keys::kInvalidUrlError, | 1031 error_ = ErrorUtils::FormatErrorMessage(keys::kInvalidUrlError, |
1031 url_string); | 1032 url_string); |
1032 return false; | 1033 return false; |
1033 } | 1034 } |
1034 } | 1035 } |
1035 | 1036 |
1036 // Don't let extensions crash the browser or renderers. | 1037 // Don't let extensions crash the browser or renderers. |
1037 if (ExtensionTabUtil::IsCrashURL(url)) { | 1038 if (ExtensionTabUtil::IsCrashURL(url)) { |
1038 error_ = keys::kNoCrashBrowserError; | 1039 error_ = keys::kNoCrashBrowserError; |
1039 return false; | 1040 return false; |
1040 } | 1041 } |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1188 std::vector<int> tab_indices; | 1189 std::vector<int> tab_indices; |
1189 EXTENSION_FUNCTION_VALIDATE(extensions::ReadOneOrMoreIntegers( | 1190 EXTENSION_FUNCTION_VALIDATE(extensions::ReadOneOrMoreIntegers( |
1190 tab_value, &tab_indices)); | 1191 tab_value, &tab_indices)); |
1191 | 1192 |
1192 // Create a new selection model as we read the list of tab indices. | 1193 // Create a new selection model as we read the list of tab indices. |
1193 for (size_t i = 0; i < tab_indices.size(); ++i) { | 1194 for (size_t i = 0; i < tab_indices.size(); ++i) { |
1194 int index = tab_indices[i]; | 1195 int index = tab_indices[i]; |
1195 | 1196 |
1196 // Make sure the index is in range. | 1197 // Make sure the index is in range. |
1197 if (!tabstrip->ContainsIndex(index)) { | 1198 if (!tabstrip->ContainsIndex(index)) { |
1198 error_ = ExtensionErrorUtils::FormatErrorMessage( | 1199 error_ = ErrorUtils::FormatErrorMessage( |
1199 keys::kTabIndexNotFoundError, base::IntToString(index)); | 1200 keys::kTabIndexNotFoundError, base::IntToString(index)); |
1200 return false; | 1201 return false; |
1201 } | 1202 } |
1202 | 1203 |
1203 // By default, we make the first tab in the list active. | 1204 // By default, we make the first tab in the list active. |
1204 if (active_index == -1) | 1205 if (active_index == -1) |
1205 active_index = index; | 1206 active_index = index; |
1206 | 1207 |
1207 selection.AddIndexToSelection(index); | 1208 selection.AddIndexToSelection(index); |
1208 } | 1209 } |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1334 if (!update_props->HasKey(keys::kUrlKey)) | 1335 if (!update_props->HasKey(keys::kUrlKey)) |
1335 return true; | 1336 return true; |
1336 | 1337 |
1337 std::string url_string; | 1338 std::string url_string; |
1338 EXTENSION_FUNCTION_VALIDATE(update_props->GetString( | 1339 EXTENSION_FUNCTION_VALIDATE(update_props->GetString( |
1339 keys::kUrlKey, &url_string)); | 1340 keys::kUrlKey, &url_string)); |
1340 GURL url = ExtensionTabUtil::ResolvePossiblyRelativeURL( | 1341 GURL url = ExtensionTabUtil::ResolvePossiblyRelativeURL( |
1341 url_string, GetExtension()); | 1342 url_string, GetExtension()); |
1342 | 1343 |
1343 if (!url.is_valid()) { | 1344 if (!url.is_valid()) { |
1344 error_ = ExtensionErrorUtils::FormatErrorMessage( | 1345 error_ = ErrorUtils::FormatErrorMessage( |
1345 keys::kInvalidUrlError, url_string); | 1346 keys::kInvalidUrlError, url_string); |
1346 return false; | 1347 return false; |
1347 } | 1348 } |
1348 | 1349 |
1349 // Don't let the extension crash the browser or renderers. | 1350 // Don't let the extension crash the browser or renderers. |
1350 if (ExtensionTabUtil::IsCrashURL(url)) { | 1351 if (ExtensionTabUtil::IsCrashURL(url)) { |
1351 error_ = keys::kNoCrashBrowserError; | 1352 error_ = keys::kNoCrashBrowserError; |
1352 return false; | 1353 return false; |
1353 } | 1354 } |
1354 | 1355 |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1465 return false; | 1466 return false; |
1466 } | 1467 } |
1467 | 1468 |
1468 // If windowId is different from the current window, move between windows. | 1469 // If windowId is different from the current window, move between windows. |
1469 if (ExtensionTabUtil::GetWindowId(target_browser) != | 1470 if (ExtensionTabUtil::GetWindowId(target_browser) != |
1470 ExtensionTabUtil::GetWindowId(source_browser)) { | 1471 ExtensionTabUtil::GetWindowId(source_browser)) { |
1471 TabStripModel* target_tab_strip = target_browser->tab_strip_model(); | 1472 TabStripModel* target_tab_strip = target_browser->tab_strip_model(); |
1472 TabContents* tab_contents = | 1473 TabContents* tab_contents = |
1473 source_tab_strip->DetachTabContentsAt(tab_index); | 1474 source_tab_strip->DetachTabContentsAt(tab_index); |
1474 if (!tab_contents) { | 1475 if (!tab_contents) { |
1475 error_ = ExtensionErrorUtils::FormatErrorMessage( | 1476 error_ = ErrorUtils::FormatErrorMessage( |
1476 keys::kTabNotFoundError, base::IntToString(tab_ids[i])); | 1477 keys::kTabNotFoundError, base::IntToString(tab_ids[i])); |
1477 return false; | 1478 return false; |
1478 } | 1479 } |
1479 | 1480 |
1480 // Clamp move location to the last position. | 1481 // Clamp move location to the last position. |
1481 // This is ">" because it can append to a new index position. | 1482 // This is ">" because it can append to a new index position. |
1482 // -1 means set the move location to the last position. | 1483 // -1 means set the move location to the last position. |
1483 if (new_index > target_tab_strip->count() || new_index < 0) | 1484 if (new_index > target_tab_strip->count() || new_index < 0) |
1484 new_index = target_tab_strip->count(); | 1485 new_index = target_tab_strip->count(); |
1485 | 1486 |
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1868 // called for every API call the extension made. | 1869 // called for every API call the extension made. |
1869 GotLanguage(language); | 1870 GotLanguage(language); |
1870 } | 1871 } |
1871 | 1872 |
1872 void DetectTabLanguageFunction::GotLanguage(const std::string& language) { | 1873 void DetectTabLanguageFunction::GotLanguage(const std::string& language) { |
1873 SetResult(Value::CreateStringValue(language.c_str())); | 1874 SetResult(Value::CreateStringValue(language.c_str())); |
1874 SendResponse(true); | 1875 SendResponse(true); |
1875 | 1876 |
1876 Release(); // Balanced in Run() | 1877 Release(); // Balanced in Run() |
1877 } | 1878 } |
OLD | NEW |