Rework of the shared resources patch for checkin

Implement shared resources and use them in bookmark manager

I had an issue with git when moving files so i had to create a new patch to
delete/readd them here.  See code review 1564034.  This is just for
trybots/checkins.

BUG=none
TEST=none

Review URL: http://codereview.chromium.org/1694019

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@45885 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/dom_ui/chrome_url_data_manager.cc b/chrome/browser/dom_ui/chrome_url_data_manager.cc
index 232a993a..ea22d76c 100644
--- a/chrome/browser/dom_ui/chrome_url_data_manager.cc
+++ b/chrome/browser/dom_ui/chrome_url_data_manager.cc
@@ -98,6 +98,13 @@
         chrome::kChromeUIDevToolsHost, inspector_dir);
   }
 
+  // Set up the chrome://resources/ source.
+  FilePath resources_dir;
+  if (PathService::Get(chrome::DIR_SHARED_RESOURCES, &resources_dir)) {
+    Singleton<ChromeURLDataManager>()->AddFileSource(
+        chrome::kChromeUIResourcesHost, resources_dir);
+  }
+
   URLRequest::RegisterProtocolFactory(chrome::kChromeUIScheme,
                                       &ChromeURLDataManager::Factory);
   URLRequest::RegisterProtocolFactory(chrome::kPrintScheme,
@@ -110,6 +117,12 @@
     Singleton<ChromeURLDataManager>()->RemoveFileSource(
         chrome::kChromeUIDevToolsHost);
   }
+
+  FilePath resources_dir;
+  if (PathService::Get(chrome::DIR_SHARED_RESOURCES, &resources_dir)) {
+    Singleton<ChromeURLDataManager>()->RemoveFileSource(
+        chrome::kChromeUIResourcesHost);
+  }
 }
 
 // static
diff --git a/chrome/browser/resources/bookmark_manager/main.html b/chrome/browser/resources/bookmark_manager/main.html
index 561a3ab..5b91326 100644
--- a/chrome/browser/resources/bookmark_manager/main.html
+++ b/chrome/browser/resources/bookmark_manager/main.html
@@ -10,34 +10,35 @@
 <head>
 <title i18n-content="title"></title>
 
-<link rel="stylesheet" href="css/list.css">
-<link rel="stylesheet" href="css/tree.css">
-<link rel="stylesheet" href="css/menu.css">
+<link rel="stylesheet" href="chrome://resources/css/list.css">
+<link rel="stylesheet" href="chrome://resources/css/tree.css">
+<link rel="stylesheet" href="chrome://resources/css/menu.css">
 <link rel="stylesheet" href="css/bmm.css">
 
-<script src="css/tree.css.js"></script>
+<script src="chrome://resources/css/tree.css.js"></script>
 <script src="css/bmm.css.js"></script>
 
-<script src="js/cr.js"></script>
-<script src="js/cr/event.js"></script>
-<script src="js/cr/eventtarget.js"></script>
-<script src="js/cr/linkcontroller.js"></script>
-<script src="js/cr/promise.js"></script>
-<script src="js/cr/ui.js"></script>
-<script src="js/cr/ui/listselectionmodel.js"></script>
-<script src="js/cr/ui/listitem.js"></script>
-<script src="js/cr/ui/list.js"></script>
-<script src="js/cr/ui/tree.js"></script>
-<script src="js/cr/ui/splitter.js"></script>
-<script src="js/cr/ui/command.js"></script>
-<script src="js/cr/ui/menuitem.js"></script>
-<script src="js/cr/ui/menu.js"></script>
-<script src="js/cr/ui/menubutton.js"></script>
-<script src="js/cr/ui/contextmenuhandler.js"></script>
+<script src="chrome://resources/js/cr.js"></script>
+<script src="chrome://resources/js/cr/event.js"></script>
+<script src="chrome://resources/js/cr/eventtarget.js"></script>
+<script src="chrome://resources/js/cr/linkcontroller.js"></script>
+<script src="chrome://resources/js/cr/promise.js"></script>
+<script src="chrome://resources/js/cr/ui.js"></script>
+<script src="chrome://resources/js/cr/ui/listselectionmodel.js"></script>
+<script src="chrome://resources/js/cr/ui/listitem.js"></script>
+<script src="chrome://resources/js/cr/ui/list.js"></script>
+<script src="chrome://resources/js/cr/ui/tree.js"></script>
+<script src="chrome://resources/js/cr/ui/splitter.js"></script>
+<script src="chrome://resources/js/cr/ui/command.js"></script>
+<script src="chrome://resources/js/cr/ui/menuitem.js"></script>
+<script src="chrome://resources/js/cr/ui/menu.js"></script>
+<script src="chrome://resources/js/cr/ui/menubutton.js"></script>
+<script src="chrome://resources/js/cr/ui/contextmenuhandler.js"></script>
 
-<script src="js/util.js"></script>
-<script src="js/localstrings.js"></script>
-<script src="js/i18ntemplate.js"></script>
+<script src="chrome://resources/js/util.js"></script>
+<script src="chrome://resources/js/localstrings.js"></script>
+<script src="chrome://resources/js/i18ntemplate.js"></script>
+
 
 <script src="js/bmm/treeiterator.js"></script>
 <script src="js/bmm.js"></script>
diff --git a/chrome/browser/resources/bookmark_manager/manifest.json b/chrome/browser/resources/bookmark_manager/manifest.json
index de24916..b9a1ea5 100644
--- a/chrome/browser/resources/bookmark_manager/manifest.json
+++ b/chrome/browser/resources/bookmark_manager/manifest.json
@@ -10,7 +10,8 @@
     "bookmarks",
     "experimental",
     "tabs",
-    "chrome://favicon/"
+    "chrome://favicon/",
+    "chrome://resources/"
   ],
   "chrome_url_overrides": {
     "bookmarks": "main.html"
diff --git a/chrome/browser/resources/bookmark_manager/css/list.css b/chrome/browser/resources/shared/css/list.css
similarity index 100%
rename from chrome/browser/resources/bookmark_manager/css/list.css
rename to chrome/browser/resources/shared/css/list.css
diff --git a/chrome/browser/resources/bookmark_manager/css/menu.css b/chrome/browser/resources/shared/css/menu.css
similarity index 100%
rename from chrome/browser/resources/bookmark_manager/css/menu.css
rename to chrome/browser/resources/shared/css/menu.css
diff --git a/chrome/browser/resources/bookmark_manager/css/tree.css b/chrome/browser/resources/shared/css/tree.css
similarity index 100%
rename from chrome/browser/resources/bookmark_manager/css/tree.css
rename to chrome/browser/resources/shared/css/tree.css
diff --git a/chrome/browser/resources/bookmark_manager/css/tree.css.js b/chrome/browser/resources/shared/css/tree.css.js
similarity index 100%
rename from chrome/browser/resources/bookmark_manager/css/tree.css.js
rename to chrome/browser/resources/shared/css/tree.css.js
diff --git a/chrome/browser/resources/bookmark_manager/js/cr.js b/chrome/browser/resources/shared/js/cr.js
similarity index 100%
rename from chrome/browser/resources/bookmark_manager/js/cr.js
rename to chrome/browser/resources/shared/js/cr.js
diff --git a/chrome/browser/resources/bookmark_manager/js/cr/event.js b/chrome/browser/resources/shared/js/cr/event.js
similarity index 100%
rename from chrome/browser/resources/bookmark_manager/js/cr/event.js
rename to chrome/browser/resources/shared/js/cr/event.js
diff --git a/chrome/browser/resources/bookmark_manager/js/cr/eventtarget.js b/chrome/browser/resources/shared/js/cr/eventtarget.js
similarity index 100%
rename from chrome/browser/resources/bookmark_manager/js/cr/eventtarget.js
rename to chrome/browser/resources/shared/js/cr/eventtarget.js
diff --git a/chrome/browser/resources/bookmark_manager/js/cr/eventtarget_test.html b/chrome/browser/resources/shared/js/cr/eventtarget_test.html
similarity index 100%
rename from chrome/browser/resources/bookmark_manager/js/cr/eventtarget_test.html
rename to chrome/browser/resources/shared/js/cr/eventtarget_test.html
diff --git a/chrome/browser/resources/bookmark_manager/js/cr/linkcontroller.js b/chrome/browser/resources/shared/js/cr/linkcontroller.js
similarity index 100%
rename from chrome/browser/resources/bookmark_manager/js/cr/linkcontroller.js
rename to chrome/browser/resources/shared/js/cr/linkcontroller.js
diff --git a/chrome/browser/resources/bookmark_manager/js/cr/linkcontroller_test.html b/chrome/browser/resources/shared/js/cr/linkcontroller_test.html
similarity index 100%
rename from chrome/browser/resources/bookmark_manager/js/cr/linkcontroller_test.html
rename to chrome/browser/resources/shared/js/cr/linkcontroller_test.html
diff --git a/chrome/browser/resources/bookmark_manager/js/cr/promise.js b/chrome/browser/resources/shared/js/cr/promise.js
similarity index 100%
rename from chrome/browser/resources/bookmark_manager/js/cr/promise.js
rename to chrome/browser/resources/shared/js/cr/promise.js
diff --git a/chrome/browser/resources/bookmark_manager/js/cr/promise_test.html b/chrome/browser/resources/shared/js/cr/promise_test.html
similarity index 100%
rename from chrome/browser/resources/bookmark_manager/js/cr/promise_test.html
rename to chrome/browser/resources/shared/js/cr/promise_test.html
diff --git a/chrome/browser/resources/bookmark_manager/js/cr/ui.js b/chrome/browser/resources/shared/js/cr/ui.js
similarity index 100%
rename from chrome/browser/resources/bookmark_manager/js/cr/ui.js
rename to chrome/browser/resources/shared/js/cr/ui.js
diff --git a/chrome/browser/resources/bookmark_manager/js/cr/ui/command.js b/chrome/browser/resources/shared/js/cr/ui/command.js
similarity index 100%
rename from chrome/browser/resources/bookmark_manager/js/cr/ui/command.js
rename to chrome/browser/resources/shared/js/cr/ui/command.js
diff --git a/chrome/browser/resources/bookmark_manager/js/cr/ui/contextmenuhandler.js b/chrome/browser/resources/shared/js/cr/ui/contextmenuhandler.js
similarity index 100%
rename from chrome/browser/resources/bookmark_manager/js/cr/ui/contextmenuhandler.js
rename to chrome/browser/resources/shared/js/cr/ui/contextmenuhandler.js
diff --git a/chrome/browser/resources/bookmark_manager/js/cr/ui/list.js b/chrome/browser/resources/shared/js/cr/ui/list.js
similarity index 100%
rename from chrome/browser/resources/bookmark_manager/js/cr/ui/list.js
rename to chrome/browser/resources/shared/js/cr/ui/list.js
diff --git a/chrome/browser/resources/bookmark_manager/js/cr/ui/listitem.js b/chrome/browser/resources/shared/js/cr/ui/listitem.js
similarity index 100%
rename from chrome/browser/resources/bookmark_manager/js/cr/ui/listitem.js
rename to chrome/browser/resources/shared/js/cr/ui/listitem.js
diff --git a/chrome/browser/resources/bookmark_manager/js/cr/ui/listselectionmodel.js b/chrome/browser/resources/shared/js/cr/ui/listselectionmodel.js
similarity index 100%
rename from chrome/browser/resources/bookmark_manager/js/cr/ui/listselectionmodel.js
rename to chrome/browser/resources/shared/js/cr/ui/listselectionmodel.js
diff --git a/chrome/browser/resources/bookmark_manager/js/cr/ui/menu.js b/chrome/browser/resources/shared/js/cr/ui/menu.js
similarity index 100%
rename from chrome/browser/resources/bookmark_manager/js/cr/ui/menu.js
rename to chrome/browser/resources/shared/js/cr/ui/menu.js
diff --git a/chrome/browser/resources/bookmark_manager/js/cr/ui/menubutton.js b/chrome/browser/resources/shared/js/cr/ui/menubutton.js
similarity index 100%
rename from chrome/browser/resources/bookmark_manager/js/cr/ui/menubutton.js
rename to chrome/browser/resources/shared/js/cr/ui/menubutton.js
diff --git a/chrome/browser/resources/bookmark_manager/js/cr/ui/menuitem.js b/chrome/browser/resources/shared/js/cr/ui/menuitem.js
similarity index 100%
rename from chrome/browser/resources/bookmark_manager/js/cr/ui/menuitem.js
rename to chrome/browser/resources/shared/js/cr/ui/menuitem.js
diff --git a/chrome/browser/resources/bookmark_manager/js/cr/ui/splitter.js b/chrome/browser/resources/shared/js/cr/ui/splitter.js
similarity index 100%
rename from chrome/browser/resources/bookmark_manager/js/cr/ui/splitter.js
rename to chrome/browser/resources/shared/js/cr/ui/splitter.js
diff --git a/chrome/browser/resources/bookmark_manager/js/cr/ui/tree.js b/chrome/browser/resources/shared/js/cr/ui/tree.js
similarity index 100%
rename from chrome/browser/resources/bookmark_manager/js/cr/ui/tree.js
rename to chrome/browser/resources/shared/js/cr/ui/tree.js
diff --git a/chrome/browser/resources/bookmark_manager/js/cr_test.html b/chrome/browser/resources/shared/js/cr_test.html
similarity index 100%
rename from chrome/browser/resources/bookmark_manager/js/cr_test.html
rename to chrome/browser/resources/shared/js/cr_test.html
diff --git a/chrome/browser/resources/bookmark_manager/js/i18ntemplate.js b/chrome/browser/resources/shared/js/i18ntemplate.js
similarity index 100%
rename from chrome/browser/resources/bookmark_manager/js/i18ntemplate.js
rename to chrome/browser/resources/shared/js/i18ntemplate.js
diff --git a/chrome/browser/resources/bookmark_manager/js/localstrings.js b/chrome/browser/resources/shared/js/localstrings.js
similarity index 100%
rename from chrome/browser/resources/bookmark_manager/js/localstrings.js
rename to chrome/browser/resources/shared/js/localstrings.js
diff --git a/chrome/browser/resources/bookmark_manager/js/util.js b/chrome/browser/resources/shared/js/util.js
similarity index 100%
rename from chrome/browser/resources/bookmark_manager/js/util.js
rename to chrome/browser/resources/shared/js/util.js
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index f676374..332e3518 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -3161,6 +3161,53 @@
       # http://code.google.com/p/gyp/issues/detail?id=143.
       'copies': [
         {
+          'destination': '<(PRODUCT_DIR)/resources/shared/css',
+          'files': [
+            'browser/resources/shared/css/list.css',
+            'browser/resources/shared/css/menu.css',
+            'browser/resources/shared/css/tree.css',
+            'browser/resources/shared/css/tree.css.js',
+          ]
+        },
+        {
+          'destination': '<(PRODUCT_DIR)/resources/shared/js',
+          'files': [
+            'browser/resources/shared/js/cr_test.html',
+            'browser/resources/shared/js/cr.js',
+            'browser/resources/shared/js/i18ntemplate.js',
+            'browser/resources/shared/js/localstrings.js',
+            'browser/resources/shared/js/util.js',        
+          ]
+        },
+        {
+          'destination': '<(PRODUCT_DIR)/resources/shared/js/cr',
+          'files': [
+            'browser/resources/shared/js/cr/event.js',
+            'browser/resources/shared/js/cr/eventtarget_test.html',
+            'browser/resources/shared/js/cr/eventtarget.js',
+            'browser/resources/shared/js/cr/linkcontroller_test.html',
+            'browser/resources/shared/js/cr/linkcontroller.js',
+            'browser/resources/shared/js/cr/promise_test.html',
+            'browser/resources/shared/js/cr/promise.js',
+            'browser/resources/shared/js/cr/ui.js',
+          ]
+        },
+        {
+          'destination': '<(PRODUCT_DIR)/resources/shared/js/cr/ui',
+          'files': [
+            'browser/resources/shared/js/cr/ui/command.js',
+            'browser/resources/shared/js/cr/ui/contextmenuhandler.js',
+            'browser/resources/shared/js/cr/ui/list.js',
+            'browser/resources/shared/js/cr/ui/listitem.js',
+            'browser/resources/shared/js/cr/ui/listselectionmodel.js',
+            'browser/resources/shared/js/cr/ui/menu.js',
+            'browser/resources/shared/js/cr/ui/menubutton.js',
+            'browser/resources/shared/js/cr/ui/menuitem.js',
+            'browser/resources/shared/js/cr/ui/splitter.js',
+            'browser/resources/shared/js/cr/ui/tree.js',
+          ]
+        },
+        {
           'destination': '<(PRODUCT_DIR)/resources/bookmark_manager',
           'files': [
             'browser/resources/bookmark_manager/main.html',
@@ -3172,45 +3219,12 @@
           'files': [
             'browser/resources/bookmark_manager/css/bmm.css',
             'browser/resources/bookmark_manager/css/bmm.css.js',
-            'browser/resources/bookmark_manager/css/list.css',
-            'browser/resources/bookmark_manager/css/menu.css',
-            'browser/resources/bookmark_manager/css/tree.css',
-            'browser/resources/bookmark_manager/css/tree.css.js',
           ]
         },
         {
           'destination': '<(PRODUCT_DIR)/resources/bookmark_manager/js',
           'files': [
             'browser/resources/bookmark_manager/js/bmm.js',
-            'browser/resources/bookmark_manager/js/cr.js',
-            'browser/resources/bookmark_manager/js/i18ntemplate.js',
-            'browser/resources/bookmark_manager/js/localstrings.js',
-            'browser/resources/bookmark_manager/js/util.js',
-          ]
-        },
-        {
-          'destination': '<(PRODUCT_DIR)/resources/bookmark_manager/js/cr',
-          'files': [
-            'browser/resources/bookmark_manager/js/cr/event.js',
-            'browser/resources/bookmark_manager/js/cr/eventtarget.js',
-            'browser/resources/bookmark_manager/js/cr/linkcontroller.js',
-            'browser/resources/bookmark_manager/js/cr/promise.js',
-            'browser/resources/bookmark_manager/js/cr/ui.js',
-          ]
-        },
-        {
-          'destination': '<(PRODUCT_DIR)/resources/bookmark_manager/js/cr/ui',
-          'files': [
-            'browser/resources/bookmark_manager/js/cr/ui/command.js',
-            'browser/resources/bookmark_manager/js/cr/ui/contextmenuhandler.js',
-            'browser/resources/bookmark_manager/js/cr/ui/list.js',
-            'browser/resources/bookmark_manager/js/cr/ui/listitem.js',
-            'browser/resources/bookmark_manager/js/cr/ui/listselectionmodel.js',
-            'browser/resources/bookmark_manager/js/cr/ui/menu.js',
-            'browser/resources/bookmark_manager/js/cr/ui/menubutton.js',
-            'browser/resources/bookmark_manager/js/cr/ui/menuitem.js',
-            'browser/resources/bookmark_manager/js/cr/ui/splitter.js',
-            'browser/resources/bookmark_manager/js/cr/ui/tree.js',
           ]
         },
         {
diff --git a/chrome/chrome_dll.gypi b/chrome/chrome_dll.gypi
index 27e648c..dd77f75 100644
--- a/chrome/chrome_dll.gypi
+++ b/chrome/chrome_dll.gypi
@@ -399,6 +399,7 @@
                   'files': [
                     '<(PRODUCT_DIR)/resources/inspector/',
                     '<(PRODUCT_DIR)/resources/bookmark_manager/',
+                    '<(PRODUCT_DIR)/resources/shared/',
                     '<(PRODUCT_DIR)/resources/gmail_app/',
                     '<(PRODUCT_DIR)/resources/calendar_app/',
                     '<(PRODUCT_DIR)/resources/docs_app/',
diff --git a/chrome/common/chrome_paths.cc b/chrome/common/chrome_paths.cc
index 3f5e055..eccb65b 100644
--- a/chrome/common/chrome_paths.cc
+++ b/chrome/common/chrome_paths.cc
@@ -151,6 +151,16 @@
       cur = cur.Append(FILE_PATH_LITERAL("resources"));
 #endif
       break;
+    case chrome::DIR_SHARED_RESOURCES:
+      if (!PathService::Get(chrome::DIR_RESOURCES, &cur))
+        return false;
+      cur = cur.Append(FILE_PATH_LITERAL("shared"));
+      break;
+    case chrome::DIR_BOOKMARK_MANAGER:
+      if (!PathService::Get(chrome::DIR_RESOURCES, &cur))
+        return false;
+      cur = cur.Append(FILE_PATH_LITERAL("bookmark_manager"));
+      break;
     case chrome::DIR_INSPECTOR:
       if (!PathService::Get(chrome::DIR_RESOURCES, &cur))
         return false;
diff --git a/chrome/common/chrome_paths.h b/chrome/common/chrome_paths.h
index 47dff30..c5e13d29 100644
--- a/chrome/common/chrome_paths.h
+++ b/chrome/common/chrome_paths.h
@@ -22,6 +22,9 @@
   DIR_USER_DESKTOP,             // Directory that correspond to the desktop.
   DIR_RESOURCES,                // Directory containing separate file resources
                                 // used by Chrome at runtime.
+  DIR_SHARED_RESOURCES,         // Directory containing js and css files used
+                                // by DOMUI and component extensions.
+  DIR_BOOKMARK_MANAGER,         // Directory containing the bookmark manager.
   DIR_INSPECTOR,                // Directory where web inspector is located.
   DIR_NET_INTERNALS,            // Directory where net internals is located.
   DIR_APP_DICTIONARIES,         // Directory where the global dictionaries are.
diff --git a/chrome/common/extensions/extension.cc b/chrome/common/extensions/extension.cc
index 8dc62d2..41d5257 100644
--- a/chrome/common/extensions/extension.cc
+++ b/chrome/common/extensions/extension.cc
@@ -1385,11 +1385,7 @@
         return false;
       }
 
-      // We support http:// and https:// as well as chrome://favicon/.
-      if (!(pattern.scheme() == chrome::kHttpScheme ||
-            pattern.scheme() == chrome::kHttpsScheme ||
-            (pattern.scheme() == chrome::kChromeUIScheme &&
-             pattern.host() == chrome::kChromeUIFavIconHost))) {
+      if (!CanAccessURL(pattern)) {
         *error = ExtensionErrorUtils::FormatErrorMessage(
             errors::kInvalidPermissionScheme, IntToString(i));
         return false;
@@ -1585,6 +1581,24 @@
   return EXTENSION_ICON_LARGE;
 }
 
+// We support http:// and https:// as well as chrome://favicon//.
+// chrome://resources/ is supported but only for component extensions.
+bool Extension::CanAccessURL(const URLPattern pattern) const{
+  if (pattern.scheme() == chrome::kHttpScheme ||
+      pattern.scheme() == chrome::kHttpsScheme) {
+    return true;
+  }
+  if (pattern.scheme() == chrome::kChromeUIScheme &&
+      pattern.host() == chrome::kChromeUIFavIconHost) {
+    return true;
+  }
+  if (location() == Extension::COMPONENT &&
+      pattern.scheme() == chrome::kChromeUIScheme) {
+    return true;
+  }
+  return false;
+}
+
 bool Extension::HasHostPermission(const GURL& url) const {
   for (URLPatternList::const_iterator host = host_permissions_.begin();
        host != host_permissions_.end(); ++host) {
diff --git a/chrome/common/extensions/extension.h b/chrome/common/extensions/extension.h
index 2cf2f85b..7a1fe93da 100644
--- a/chrome/common/extensions/extension.h
+++ b/chrome/common/extensions/extension.h
@@ -260,6 +260,12 @@
   // through content scripts and the hosts accessible through XHR.
   const std::set<std::string> GetEffectiveHostPermissions() const;
 
+  // Whether or not the extension is allowed permission for a URL pattern from
+  // the manifest.  http, https, and chrome://favicon/ is allowed for all
+  // extensions, while component extensions are allowed access to
+  // chrome://resources.
+  bool CanAccessURL(const URLPattern pattern) const;
+
   // Whether the extension has access to the given URL.
   bool HasHostPermission(const GURL& url) const;
 
diff --git a/chrome/common/extensions/extension_manifests_unittest.cc b/chrome/common/extensions/extension_manifests_unittest.cc
index 66f8991..36e0266 100644
--- a/chrome/common/extensions/extension_manifests_unittest.cc
+++ b/chrome/common/extensions/extension_manifests_unittest.cc
@@ -23,6 +23,12 @@
  protected:
   Extension* LoadExtension(const std::string& name,
                            std::string* error) {
+    return LoadExtensionWithLocation(name, Extension::INTERNAL, error);
+  }
+
+  Extension* LoadExtensionWithLocation(const std::string& name,
+                                       Extension::Location location,
+                                       std::string* error) {
     FilePath path;
     PathService::Get(chrome::DIR_TEST_DATA, &path);
     path = path.AppendASCII("extensions")
@@ -37,6 +43,7 @@
       return NULL;
 
     scoped_ptr<Extension> extension(new Extension(path.DirName()));
+    extension->set_location(location);
     if (enable_apps_)
       extension->set_apps_enabled(true);
 
@@ -191,6 +198,18 @@
       errors::kInvalidPermissionScheme);
 }
 
+TEST_F(ManifestTest, ChromeResourcesPermissionValidOnlyForComponents) {
+  LoadAndExpectError("permission_chrome_resources_url.json",
+      errors::kInvalidPermissionScheme);
+  std::string error;
+  scoped_ptr<Extension> extension;
+  extension.reset(LoadExtensionWithLocation(
+      "permission_chrome_resources_url.json",
+      Extension::COMPONENT,
+      &error));
+  EXPECT_EQ("", error);
+}
+
 TEST_F(ManifestTest, ChromeURLContentScriptInvalid) {
   LoadAndExpectError("content_script_chrome_url_invalid.json",
       errors::kInvalidMatch);
diff --git a/chrome/common/url_constants.cc b/chrome/common/url_constants.cc
index 513ee611..8b3e45b 100644
--- a/chrome/common/url_constants.cc
+++ b/chrome/common/url_constants.cc
@@ -74,6 +74,7 @@
 const char kChromeUIFavIconHost[] = "favicon";
 const char kChromeUIHistoryHost[] = "history";
 const char kChromeUIPluginsHost[] = "plugins";
+const char kChromeUIResourcesHost[] = "resources";
 const char kChromeUIFileBrowseHost[] = "filebrowse";
 const char kChromeUIMediaplayerHost[] = "mediaplayer";
 const char kChromeUIInspectorHost[] = "inspector";
diff --git a/chrome/common/url_constants.h b/chrome/common/url_constants.h
index b223f46..741a372 100644
--- a/chrome/common/url_constants.h
+++ b/chrome/common/url_constants.h
@@ -72,6 +72,7 @@
 extern const char kChromeUIFavIconHost[];
 extern const char kChromeUIHistoryHost[];
 extern const char kChromeUIPluginsHost[];
+extern const char kChromeUIResourcesHost[];
 extern const char kChromeUIFileBrowseHost[];
 extern const char kChromeUIMediaplayerHost[];
 extern const char kChromeUIInspectorHost[];
diff --git a/chrome/test/data/extensions/manifest_tests/permission_chrome_resources_url.json b/chrome/test/data/extensions/manifest_tests/permission_chrome_resources_url.json
new file mode 100644
index 0000000..fa778e44
--- /dev/null
+++ b/chrome/test/data/extensions/manifest_tests/permission_chrome_resources_url.json
@@ -0,0 +1,7 @@
+{
+  "name": "test",
+  "version": "1",
+  "permissions": [
+    "chrome://resources/"
+  ]
+}