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

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

Issue 13604005: Prevent chrome.app JSON schema from loading on every page (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 7 years, 8 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
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/renderer/extensions/dispatcher.h" 5 #include "chrome/renderer/extensions/dispatcher.h"
6 6
7 #include "base/callback.h" 7 #include "base/callback.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/memory/scoped_ptr.h" 9 #include "base/memory/scoped_ptr.h"
10 #include "base/strings/string_piece.h" 10 #include "base/strings/string_piece.h"
(...skipping 643 matching lines...) Expand 10 before | Expand all | Expand 10 after
654 int world_id) { 654 int world_id) {
655 g_hack_extension_group = extension_group; 655 g_hack_extension_group = extension_group;
656 return true; 656 return true;
657 } 657 }
658 658
659 v8::Handle<v8::Object> Dispatcher::GetOrCreateObject( 659 v8::Handle<v8::Object> Dispatcher::GetOrCreateObject(
660 v8::Handle<v8::Object> object, 660 v8::Handle<v8::Object> object,
661 const std::string& field) { 661 const std::string& field) {
662 v8::HandleScope handle_scope; 662 v8::HandleScope handle_scope;
663 v8::Handle<v8::String> key = v8::String::New(field.c_str()); 663 v8::Handle<v8::String> key = v8::String::New(field.c_str());
664 // This little dance is for APIs that may be unavailable but have available 664 // If the object has a callback property, it is assumed it is an unavailable
665 // children. For example, chrome.app can be unavailable, while 665 // API, so it is safe to delete. This is checked before GetOrCreateObject is
666 // chrome.app.runtime is available. The lazy getter for chrome.app must be 666 // called.
667 // deleted, so that there isn't an error when accessing chrome.app.runtime. 667 if (object->HasRealNamedCallbackProperty(key)) {
668 if (object->Has(key)) { 668 object->Delete(key);
669 } else if (object->HasRealNamedProperty(key)) {
669 v8::Handle<v8::Value> value = object->Get(key); 670 v8::Handle<v8::Value> value = object->Get(key);
670 if (value->IsObject()) 671 CHECK(value->IsObject());
671 return handle_scope.Close(v8::Handle<v8::Object>::Cast(value)); 672 return handle_scope.Close(v8::Handle<v8::Object>::Cast(value));
672 else
673 object->Delete(key);
674 } 673 }
675 674
676 v8::Handle<v8::Object> new_object = v8::Object::New(); 675 v8::Handle<v8::Object> new_object = v8::Object::New();
677 object->Set(key, new_object); 676 object->Set(key, new_object);
678 return handle_scope.Close(new_object); 677 return handle_scope.Close(new_object);
679 } 678 }
680 679
681 void Dispatcher::RegisterSchemaGeneratedBindings( 680 void Dispatcher::RegisterSchemaGeneratedBindings(
682 ModuleSystem* module_system, 681 ModuleSystem* module_system,
683 ChromeV8Context* context, 682 ChromeV8Context* context) {
684 v8::Handle<v8::Context> v8_context) {
685 std::set<std::string> apis = 683 std::set<std::string> apis =
686 ExtensionAPI::GetSharedInstance()->GetAllAPINames(); 684 ExtensionAPI::GetSharedInstance()->GetAllAPINames();
687 for (std::set<std::string>::iterator it = apis.begin(); 685 for (std::set<std::string>::iterator it = apis.begin();
688 it != apis.end(); ++it) { 686 it != apis.end(); ++it) {
689 const std::string& api_name = *it; 687 const std::string& api_name = *it;
688 if (!context->GetAvailabilityForContext(api_name).is_available())
689 continue;
690 690
691 Feature* feature = 691 Feature* feature =
692 BaseFeatureProvider::GetByName("api")->GetFeature(api_name); 692 BaseFeatureProvider::GetByName("api")->GetFeature(api_name);
693 if (feature && feature->IsInternal()) 693 if (feature && feature->IsInternal())
694 continue; 694 continue;
695 695
696 std::vector<std::string> split; 696 std::vector<std::string> split;
697 base::SplitString(api_name, '.', &split); 697 base::SplitString(api_name, '.', &split);
698 698
699 v8::Handle<v8::Object> bind_object = GetOrCreateChrome(v8_context); 699 v8::Handle<v8::Object> bind_object =
700 for (size_t i = 0; i < split.size() - 1; ++i) 700 GetOrCreateChrome(context->v8_context());
701
702 // Check if this API has an ancestor. If the API's ancestor is available and
703 // the API is not available, don't install the bindings for this API. If
704 // the API is available and its ancestor is not, delete the ancestor and
705 // install the bindings for the API. This is to prevent loading the ancestor
706 // API schema if it will not be needed.
707 //
708 // For example:
709 // If app is available and app.window is not, just install app.
710 // If app.window is available and app is not, delete app and install
711 // app.window on a new object so app does not have to be loaded.
712 std::string ancestor_name;
713 bool only_ancestor_available = false;
714 for (size_t i = 0; i < split.size() - 1; ++i) {
715 ancestor_name += (i ? ".": "") + split[i];
716 if (!ancestor_name.empty() &&
717 context->GetAvailability(ancestor_name).is_available() &&
718 !context->GetAvailability(api_name).is_available()) {
719 only_ancestor_available = true;
720 break;
721 }
701 bind_object = GetOrCreateObject(bind_object, split[i]); 722 bind_object = GetOrCreateObject(bind_object, split[i]);
723 }
724 if (only_ancestor_available)
725 continue;
702 726
703 if (lazy_bindings_map_.find(api_name) != lazy_bindings_map_.end()) { 727 if (lazy_bindings_map_.find(api_name) != lazy_bindings_map_.end()) {
704 InstallBindings(module_system, v8_context, api_name); 728 InstallBindings(module_system, context->v8_context(), api_name);
705 } else if (!source_map_.Contains(api_name)) { 729 } else if (!source_map_.Contains(api_name)) {
706 module_system->RegisterNativeHandler( 730 module_system->RegisterNativeHandler(
707 api_name, 731 api_name,
708 scoped_ptr<NativeHandler>(new BindingGeneratingNativeHandler( 732 scoped_ptr<NativeHandler>(new BindingGeneratingNativeHandler(
709 module_system, 733 module_system,
710 api_name, 734 api_name,
711 "binding"))); 735 "binding")));
712 module_system->SetNativeLazyField(bind_object, 736 module_system->SetNativeLazyField(bind_object,
713 split.back(), 737 split.back(),
714 api_name, 738 api_name,
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
983 BackgroundInfo::HasLazyBackgroundPage(extension)); 1007 BackgroundInfo::HasLazyBackgroundPage(extension));
984 module_system->RegisterNativeHandler("process", 1008 module_system->RegisterNativeHandler("process",
985 scoped_ptr<NativeHandler>(new ProcessInfoNativeHandler( 1009 scoped_ptr<NativeHandler>(new ProcessInfoNativeHandler(
986 this, v8_context, context->GetExtensionID(), 1010 this, v8_context, context->GetExtensionID(),
987 context->GetContextTypeDescription(), 1011 context->GetContextTypeDescription(),
988 ChromeRenderProcessObserver::is_incognito_process(), 1012 ChromeRenderProcessObserver::is_incognito_process(),
989 manifest_version, send_request_disabled))); 1013 manifest_version, send_request_disabled)));
990 1014
991 GetOrCreateChrome(v8_context); 1015 GetOrCreateChrome(v8_context);
992 1016
993 // Loading JavaScript is expensive, so only run the full API bindings 1017 // TODO(kalman): see comment below about ExtensionAPI.
994 // generation mechanisms in extension pages (NOT all web pages). 1018 if (extension && !extension->is_platform_app())
995 switch (context_type) { 1019 module_system->Require("miscellaneous_bindings");
996 case Feature::UNSPECIFIED_CONTEXT: 1020 if (context_type != Feature::WEB_PAGE_CONTEXT)
997 case Feature::WEB_PAGE_CONTEXT: 1021 module_system->Require("json"); // see paranoid comment in json.js
998 // TODO(kalman): see comment below about ExtensionAPI.
999 InstallBindings(module_system.get(), v8_context, "app");
1000 InstallBindings(module_system.get(), v8_context, "webstore");
1001 break;
1002 case Feature::BLESSED_EXTENSION_CONTEXT:
1003 case Feature::UNBLESSED_EXTENSION_CONTEXT:
1004 case Feature::CONTENT_SCRIPT_CONTEXT:
1005 if (extension && !extension->is_platform_app())
1006 module_system->Require("miscellaneous_bindings");
1007 module_system->Require("json"); // see paranoid comment in json.js
1008 1022
1009 // TODO(kalman): move this code back out of the switch and execute it 1023 RegisterSchemaGeneratedBindings(module_system.get(), context);
1010 // regardless of |context_type|. ExtensionAPI knows how to return the
1011 // correct APIs, however, until it doesn't have a 2MB overhead we can't
1012 // load it in every process.
1013 RegisterSchemaGeneratedBindings(module_system.get(),
1014 context,
1015 v8_context);
1016 break;
1017 }
1018 1024
1019 bool is_within_platform_app = IsWithinPlatformApp(frame); 1025 bool is_within_platform_app = IsWithinPlatformApp(frame);
1020 // Inject custom JS into the platform app context. 1026 // Inject custom JS into the platform app context.
1021 if (is_within_platform_app) 1027 if (is_within_platform_app)
1022 module_system->Require("platformApp"); 1028 module_system->Require("platformApp");
1023 1029
1024 // Only platform apps support the <webview> tag, because the "webView" and 1030 // Only platform apps support the <webview> tag, because the "webView" and
1025 // "denyWebView" modules will affect the performance of DOM modifications 1031 // "denyWebView" modules will affect the performance of DOM modifications
1026 // (http://crbug.com/196453). 1032 // (http://crbug.com/196453).
1027 if (context_type == Feature::BLESSED_EXTENSION_CONTEXT && 1033 if (context_type == Feature::BLESSED_EXTENSION_CONTEXT &&
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after
1381 std::string error_msg = base::StringPrintf(kMessage, function_name.c_str()); 1387 std::string error_msg = base::StringPrintf(kMessage, function_name.c_str());
1382 v8::ThrowException( 1388 v8::ThrowException(
1383 v8::Exception::Error(v8::String::New(error_msg.c_str()))); 1389 v8::Exception::Error(v8::String::New(error_msg.c_str())));
1384 return false; 1390 return false;
1385 } 1391 }
1386 1392
1387 return true; 1393 return true;
1388 } 1394 }
1389 1395
1390 } // namespace extensions 1396 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/renderer/extensions/dispatcher.h ('k') | chrome/test/data/extensions/api_test/crazy_extension/background.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698