diff --git a/includes/theme.inc b/includes/theme.inc index adbffbe92a600450ee4489cb071570326d1e4415..9a2cc0fe0b01fb771e5c8d01d2cfe77f26748729 100644 --- a/includes/theme.inc +++ b/includes/theme.inc @@ -604,9 +604,7 @@ function list_themes($refresh = FALSE) { } } foreach ($theme->info['scripts'] as $script => $path) { - if (file_exists($path)) { - $theme->scripts[$script] = $path; - } + $theme->scripts[$script] = $path; } if (isset($theme->info['engine'])) { $theme->engine = $theme->info['engine']; @@ -2274,6 +2272,7 @@ function template_preprocess_page(&$variables) { $variables['theme_hook_suggestions'] = $suggestions; } } + /** * Process variables for html.tpl.php * diff --git a/modules/aggregator/aggregator.info b/modules/aggregator/aggregator.info index d94344022dfa7a0cc1ae06931613a9e19a13f13a..ae67bbb83f5da3f9cb57a3f303daa9ab42f3dd99 100644 --- a/modules/aggregator/aggregator.info +++ b/modules/aggregator/aggregator.info @@ -13,3 +13,4 @@ files[] = aggregator.processor.inc files[] = aggregator.install files[] = aggregator.test configure = admin/config/services/aggregator/settings +stylesheets[all][] = aggregator.css diff --git a/modules/aggregator/aggregator.module b/modules/aggregator/aggregator.module index b82bb64844ef2815670295a558d47b98b83809d7..d9afbe66fb4b6cdbfcd2112232522790baa7ccff 100644 --- a/modules/aggregator/aggregator.module +++ b/modules/aggregator/aggregator.module @@ -282,13 +282,6 @@ function _aggregator_category_title($category) { return $category['title']; } -/** - * Implements hook_init(). - */ -function aggregator_init() { - drupal_add_css(drupal_get_path('module', 'aggregator') . '/aggregator.css', array('preprocess' => TRUE)); -} - /** * Find out whether there are any aggregator categories. * diff --git a/modules/book/book.info b/modules/book/book.info index 8f74f59bc2a862eb7a4c69f5b192c19ad0724b33..c9dd5b97e28ad7f7de8a677783eb6651ea205027 100644 --- a/modules/book/book.info +++ b/modules/book/book.info @@ -10,3 +10,4 @@ files[] = book.pages.inc files[] = book.install files[] = book.test configure = admin/content/book/settings +stylesheets[all][] = book.css diff --git a/modules/book/book.module b/modules/book/book.module index b30acce9b888cfe8f1531b354b6c02ffbbf8a0b7..ef2d839986ecf2d3626f0f2f9d6d4f8ae84f86f2 100644 --- a/modules/book/book.module +++ b/modules/book/book.module @@ -214,13 +214,6 @@ function book_admin_paths() { return $paths; } -/** - * Implements hook_init(). - */ -function book_init() { - drupal_add_css(drupal_get_path('module', 'book') . '/book.css', array('preprocess' => TRUE)); -} - /** * Implements hook_entity_info_alter(). */ diff --git a/modules/comment/comment.info b/modules/comment/comment.info index 9e2c14b58e0b8a7fbe8f1a437650d24a57018561..b4374c3c69e26fdc8072b6cfc24b08a97b19087c 100644 --- a/modules/comment/comment.info +++ b/modules/comment/comment.info @@ -12,3 +12,4 @@ files[] = comment.install files[] = comment.test files[] = comment.tokens.inc configure = admin/content/comment +stylesheets[all][] = comment.css diff --git a/modules/comment/comment.module b/modules/comment/comment.module index a8b8a662f839ea8518a29864ac1049b4750be8e8..3d8d2a5d66a2b009027083ad09878395d694b14f 100644 --- a/modules/comment/comment.module +++ b/modules/comment/comment.module @@ -289,13 +289,6 @@ function comment_menu() { return $items; } -/** - * Implements hook_init(). - */ -function comment_init() { - drupal_add_css(drupal_get_path('module', 'comment') . '/comment.css', array('preprocess' => TRUE)); -} - /** * Implements hook_menu_alter(). */ diff --git a/modules/field/field.info b/modules/field/field.info index 60c429778df0e8df40f0070efb5ada292a2d119c..06de4084fdb370d0b3102a368f5805fb359a526b 100644 --- a/modules/field/field.info +++ b/modules/field/field.info @@ -15,3 +15,4 @@ files[] = field.form.inc files[] = tests/field.test dependencies[] = field_sql_storage required = TRUE +stylesheets[all][] = theme/field.css diff --git a/modules/field/field.module b/modules/field/field.module index 8ecfa44588b9ee323a4e8d30b91280f789c0fab8..fdff56298c5ad483ad87be8776a1198477508720 100644 --- a/modules/field/field.module +++ b/modules/field/field.module @@ -168,13 +168,6 @@ function field_theme() { ); } -/** - * Implements hook_init(). - */ -function field_init() { - drupal_add_css(drupal_get_path('module', 'field') . '/theme/field.css', array('preprocess' => TRUE)); -} - /** * Implements hook_cron(). * diff --git a/modules/forum/forum.info b/modules/forum/forum.info index a6fec2ccb305b7a1aaf784e9bc125403ebb70925..d4998fc3853b507c81d71cd5edad6438d936fdda 100644 --- a/modules/forum/forum.info +++ b/modules/forum/forum.info @@ -12,3 +12,4 @@ files[] = forum.pages.inc files[] = forum.install files[] = forum.test configure = admin/structure/forum +stylesheets[all][] = forum.css diff --git a/modules/forum/forum.module b/modules/forum/forum.module index 5b92d0d2e8284e96aeac597e4618a9b28ad10927..bc6a132fc1b04b2a6bb60d1ddc1e989cdb52d553 100644 --- a/modules/forum/forum.module +++ b/modules/forum/forum.module @@ -217,13 +217,6 @@ function forum_menu_local_tasks_alter(&$data, $router_item, $root_path) { } } -/** - * Implements hook_init(). - */ -function forum_init() { - drupal_add_css(drupal_get_path('module', 'forum') . '/forum.css', array('preprocess' => TRUE)); -} - /** * Implements hook_entity_info_alter(). */ diff --git a/modules/node/node.info b/modules/node/node.info index 51130138d6a28099445e521432ddd097fb94d022..23cc230995e2850395c1b3c939b1ebe7ec9bff1f 100644 --- a/modules/node/node.info +++ b/modules/node/node.info @@ -13,3 +13,4 @@ files[] = node.test files[] = node.tokens.inc required = TRUE configure = admin/structure/types +stylesheets[all][] = node.css diff --git a/modules/node/node.module b/modules/node/node.module index 8bacba7a5b7a9d99ed4341bf20e7d55617ddcbca..920e305bcf1f649199e03f31b40cd6d47a6f90d5 100644 --- a/modules/node/node.module +++ b/modules/node/node.module @@ -2012,13 +2012,6 @@ function _node_custom_theme() { } } -/** - * Implements hook_init(). - */ -function node_init() { - drupal_add_css(drupal_get_path('module', 'node') . '/node.css', array('preprocess' => TRUE)); -} - function node_last_changed($nid) { return db_query('SELECT changed FROM {node} WHERE nid = :nid', array(':nid' => $nid))->fetch()->changed; } diff --git a/modules/poll/poll.info b/modules/poll/poll.info index fd2f3149b8e04d29c8c44c1a61d467bf0c52a12d..a61b1ec66ce962215bd19a28cc4811bad2cb4fa0 100644 --- a/modules/poll/poll.info +++ b/modules/poll/poll.info @@ -9,3 +9,4 @@ files[] = poll.pages.inc files[] = poll.install files[] = poll.test files[] = poll.tokens.inc +stylesheets[all][] = poll.css diff --git a/modules/poll/poll.module b/modules/poll/poll.module index 3d38f46b01fd9e3310a8701285f9f423a5db7f3a..1de52b55f374f4439bf8b11b0c033266c92d4e2f 100644 --- a/modules/poll/poll.module +++ b/modules/poll/poll.module @@ -27,13 +27,6 @@ function poll_help($path, $arg) { } } -/** - * Implements hook_init(). - */ -function poll_init() { - drupal_add_css(drupal_get_path('module', 'poll') . '/poll.css', array('preprocess' => TRUE)); -} - /** * Implements hook_theme(). */ diff --git a/modules/search/search.info b/modules/search/search.info index eb749d281aea428bb0beea9e2d36087f360fedb7..1483074a25ee77046919ebb251ebd37b6103d65f 100644 --- a/modules/search/search.info +++ b/modules/search/search.info @@ -11,3 +11,4 @@ files[] = search.install files[] = search.test files[] = search.extender.inc configure = admin/config/search/settings +stylesheets[all][] = search.css diff --git a/modules/search/search.module b/modules/search/search.module index b5a135c2bb91e6e786986e19230e807fc6460cba..a66f1b96afeea04d0bcf71a29cc62c994a4071ec 100644 --- a/modules/search/search.module +++ b/modules/search/search.module @@ -97,13 +97,6 @@ function search_help($path, $arg) { } } -/** - * Implements hook_init(). - */ -function search_init() { - drupal_add_css(drupal_get_path('module', 'search') . '/search.css', array('preprocess' => TRUE)); -} - /** * Implements hook_theme(). */ diff --git a/modules/simpletest/tests/common.test b/modules/simpletest/tests/common.test index 0f44bea891fb03e8c38d6353cda6b63a1c02e193..b23e8e53c7274ac63b5203a7a9e0eedeb4cb6759 100644 --- a/modules/simpletest/tests/common.test +++ b/modules/simpletest/tests/common.test @@ -580,6 +580,27 @@ class CascadingStylesheetsTestCase extends DrupalWebTestCase { $this->assertEqual(array(), drupal_add_css(), t('Default CSS is empty.')); } + /** + * Test that stylesheets in module .info files are loaded. + */ + function testModuleInfo() { + $this->drupalGet(''); + + // Verify common_test.css in a STYLE media="all" tag. + $elements = $this->xpath('//style[@media=:media and contains(text(), :filename)]', array( + ':media' => 'all', + ':filename' => 'tests/common_test.css', + )); + $this->assertTrue(count($elements), "Stylesheet with media 'all' in module .info file found."); + + // Verify common_test.print.css in a STYLE media="print" tag. + $elements = $this->xpath('//style[@media=:media and contains(text(), :filename)]', array( + ':media' => 'print', + ':filename' => 'tests/common_test.print.css', + )); + $this->assertTrue(count($elements), "Stylesheet with media 'print' in module .info file found."); + } + /** * Tests adding a file stylesheet. */ diff --git a/modules/simpletest/tests/common_test.info b/modules/simpletest/tests/common_test.info index 81a15472a24dc00b35bda29931d55bd26b322255..7b27416aee41904e97a53002b502edb32d375975 100644 --- a/modules/simpletest/tests/common_test.info +++ b/modules/simpletest/tests/common_test.info @@ -5,4 +5,6 @@ package = Testing version = VERSION core = 7.x files[] = common_test.module +stylesheets[all][] = common_test.css +stylesheets[print][] = common_test.print.css hidden = TRUE diff --git a/modules/system/system.api.php b/modules/system/system.api.php index 276d39f8bbf299ab59c94c588bd7c6b31aeb12fc..ebd4f20ed35121c6b6af6364ceabc75364ded529 100644 --- a/modules/system/system.api.php +++ b/modules/system/system.api.php @@ -1441,9 +1441,10 @@ function hook_boot() { * used to set up global parameters which are needed later in the request. * when this hook is called, all modules are already loaded in memory. * - * For example, this hook is a typical place for modules to add CSS or JS - * that should be present on every page. This hook is not run on cached - * pages - though CSS or JS added this way will be present on a cached page. + * This hook is not run on cached pages. + * + * To add CSS or JS that should be present on all pages, modules should not + * implement this hook, but declare these files in their .info file. */ function hook_init() { drupal_add_css(drupal_get_path('module', 'book') . '/book.css'); @@ -3955,7 +3956,7 @@ function hook_filetransfer_backends() { /** * Control site status before menu dispatching. * - * The hook is called after checking whether the site is offline but before + * The hook is called after checking whether the site is offline but before * the current router item is retrieved and executed by * menu_execute_active_handler(). If the site is in offline mode, * $menu_site_status is set to MENU_SITE_OFFLINE. diff --git a/modules/system/system.module b/modules/system/system.module index 33f232f747bc6dbdf6d6be78d1cfa49e0a4728f9..f0cab512cae70143c71cf8311187bbf777dda782 100644 --- a/modules/system/system.module +++ b/modules/system/system.module @@ -1837,7 +1837,6 @@ function system_init() { drupal_add_css($path . '/system-menus.css', array('weight' => CSS_SYSTEM, 'preprocess' => TRUE)); drupal_add_css($path . '/system-messages.css', array('weight' => CSS_SYSTEM, 'preprocess' => TRUE)); - // Ignore slave database servers for this request. // // In Drupal's distributed database structure, new data is written to the master @@ -1859,6 +1858,29 @@ function system_init() { unset($_SESSION['ignore_slave_server']); } } + + // Add CSS/JS files from module .info files. + system_add_module_assets(); +} + +/** + * Adds CSS and JavaScript files declared in module .info files. + */ +function system_add_module_assets() { + foreach (system_get_info('module') as $module => $info) { + if (!empty($info['stylesheets'])) { + foreach ($info['stylesheets'] as $media => $stylesheets) { + foreach ($stylesheets as $stylesheet) { + drupal_add_css($stylesheet, array('media' => $media, 'preprocess' => TRUE)); + } + } + } + if (!empty($info['scripts'])) { + foreach ($info['scripts'] as $script) { + drupal_add_js($script, array('preprocess' => TRUE)); + } + } + } } /** @@ -2305,6 +2327,15 @@ function _system_rebuild_module_data() { // Merge in defaults and save. $modules[$key]->info = $module->info + $defaults; + // Prefix stylesheets and scripts with module path. + $path = dirname($module->uri); + if (isset($module->info['stylesheets'])) { + $module->info['stylesheets'] = _system_info_add_path($module->info['stylesheets'], $path); + } + if (isset($module->info['scripts'])) { + $module->info['scripts'] = _system_info_add_path($module->info['scripts'], $path); + } + // Install profiles are hidden by default, unless explicitly specified // otherwise in the .info file. if ($key == $profile && !isset($modules[$key]->info['hidden'])) { @@ -2396,6 +2427,8 @@ function _system_rebuild_theme_data() { 'features' => _system_default_theme_features(), 'screenshot' => 'screenshot.png', 'php' => DRUPAL_MINIMUM_PHP, + 'stylesheets' => array(), + 'scripts' => array(), ); $sub_themes = array(); @@ -2428,28 +2461,14 @@ function _system_rebuild_theme_data() { } } - // Give the stylesheets proper path information. - $pathed_stylesheets = array(); - if (isset($themes[$key]->info['stylesheets'])) { - foreach ($themes[$key]->info['stylesheets'] as $media => $stylesheets) { - foreach ($stylesheets as $stylesheet) { - $pathed_stylesheets[$media][$stylesheet] = dirname($themes[$key]->uri) . '/' . $stylesheet; - } - } - } - $themes[$key]->info['stylesheets'] = $pathed_stylesheets; + // Prefix stylesheets and scripts with module path. + $path = dirname($theme->uri); + $theme->info['stylesheets'] = _system_info_add_path($theme->info['stylesheets'], $path); + $theme->info['scripts'] = _system_info_add_path($theme->info['scripts'], $path); - // Give the scripts proper path information. - $scripts = array(); - if (isset($themes[$key]->info['scripts'])) { - foreach ($themes[$key]->info['scripts'] as $script) { - $scripts[$script] = dirname($themes[$key]->uri) . '/' . $script; - } - } - $themes[$key]->info['scripts'] = $scripts; // Give the screenshot proper path information. if (!empty($themes[$key]->info['screenshot'])) { - $themes[$key]->info['screenshot'] = dirname($themes[$key]->uri) . '/' . $themes[$key]->info['screenshot']; + $themes[$key]->info['screenshot'] = $path . '/' . $themes[$key]->info['screenshot']; } } @@ -2496,6 +2515,41 @@ function system_rebuild_theme_data() { return $themes; } +/** + * Prefixes all values in an .info file array with a given path. + * + * This helper function is mainly used to prefix all array values of an .info + * file property with a single given path (to the module or theme); e.g., to + * prefix all values of the 'stylesheets' or 'scripts' properties with the file + * path to the defining module/theme. + * + * @param $info + * A nested array of data of an .info file to be processed. + * @param $path + * A file path to prepend to each value in $info. + * + * @return + * The $info array with prefixed values. + * + * @see _system_rebuild_module_data() + * @see _system_rebuild_theme_data() + */ +function _system_info_add_path($info, $path) { + foreach ($info as $key => $value) { + // Recurse into nested values until we reach the deepest level. + if (is_array($value)) { + $info[$key] = _system_info_add_path($info[$key], $path); + } + // Unset the original value's key and set the new value with prefix, using + // the original value as key, so original values can still be looked up. + else { + unset($info[$key]); + $info[$value] = $path . '/' . $value; + } + } + return $info; +} + /** * Returns an array of default theme features. */ diff --git a/modules/user/user.info b/modules/user/user.info index 338d89e78bbd46076e73203ef63d74c76770a001..cfe9c15a8cd8a57efb950c9caa0864a826a4437b 100644 --- a/modules/user/user.info +++ b/modules/user/user.info @@ -12,3 +12,4 @@ files[] = user.test files[] = user.tokens.inc required = TRUE configure = admin/config/people +stylesheets[all][] = user.css diff --git a/modules/user/user.module b/modules/user/user.module index 26335081e80b7f724f9a379f373f25efb91dfbec..403b42899ddf819c2f60c55aa032f0d566f4791e 100644 --- a/modules/user/user.module +++ b/modules/user/user.module @@ -1798,13 +1798,6 @@ function user_admin_paths() { return $paths; } -/** - * Implements hook_init(). - */ -function user_init() { - drupal_add_css(drupal_get_path('module', 'user') . '/user.css', array('preprocess' => TRUE)); -} - /** * Load either a specified or the current user account. * diff --git a/themes/bartik/bartik.info b/themes/bartik/bartik.info index c300b94c99e425c6bafe01fe61dd942746d75a04..689fcc330de7ef249159bdb9fa5c5a06dc0bba16 100644 --- a/themes/bartik/bartik.info +++ b/themes/bartik/bartik.info @@ -12,8 +12,6 @@ stylesheets[all][] = css/style.css stylesheets[all][] = css/colors.css stylesheets[print][] = css/print.css -scripts[] = scripts/search.js - regions[header] = Header regions[help] = Help regions[page_top] = Page top