diff --git a/core/includes/common.inc b/core/includes/common.inc index 17e1363..ae3f6ac 100644 --- a/core/includes/common.inc +++ b/core/includes/common.inc @@ -533,6 +533,35 @@ function drupal_get_destination() { } /** + * Utility method to get the normalized type of the current request. + * + * Fetches the ContentNegotiation and Request objects from the current container + * and returns the associated request content type. The normalized type is a + * short, lowercase version of the format, such as 'html', 'json' or 'atom'. + * + * @return string + * The request type + */ +function drupal_get_request_content_type() { + $type = &drupal_static(__FUNCTION__); + + if (isset($type)) { + return $type; + } + else { + $container = drupal_container(); + if ($container->has('request') && + $container->has('content_negotiation')) { + $type = $container->get('content_negotiation')->getContentType($container->get('request')); + } + else { + $type = FALSE; + } + } + return $type; +} + +/** * Parses a system URL string into an associative array suitable for url(). * * This function should only be used for URLs that have been generated by the @@ -2720,18 +2749,6 @@ function drupal_get_css($css = NULL, $skip_alter = FALSE) { // Sort CSS items, so that they appear in the correct order. uasort($css, 'drupal_sort_css_js'); - // Provide the page with information about the individual CSS files used, - // information not otherwise available when CSS aggregation is enabled. The - // setting is attached later in this function, but is set here, so that CSS - // files removed below are still considered "used" and prevented from being - // added in a later AJAX request. - // Skip if no files were added to the page or jQuery.extend() will overwrite - // the Drupal.settings.ajaxPageState.css object with an empty array. - if (!empty($css)) { - // Cast the array to an object to be on the safe side even if not empty. - $setting['ajaxPageState']['css'] = (object) array_fill_keys(array_keys($css), 1); - } - // Remove the overridden CSS files. Later CSS files override former ones. $previous_item = array(); foreach ($css as $key => $item) { @@ -3799,53 +3816,7 @@ function drupal_add_js($data = NULL, $options = NULL) { // Tweak the weight so that files of the same weight are included in the // order of the calls to drupal_add_js(). $options['weight'] += count($javascript) / 1000; - if (isset($data)) { - // Add jquery.js and drupal.js, as well as the basePath setting, the - // first time a JavaScript file is added. - if (empty($javascript)) { - // url() generates the script and prefix using hook_url_outbound_alter(). - // Instead of running the hook_url_outbound_alter() again here, extract - // them from url(). - // @todo Make this less hacky: http://drupal.org/node/1547376. - $scriptPath = $GLOBALS['script_path']; - $pathPrefix = ''; - url('', array('script' => &$scriptPath, 'prefix' => &$pathPrefix)); - $javascript = array( - 'settings' => array( - 'data' => array( - array('basePath' => base_path()), - array('scriptPath' => $scriptPath), - array('pathPrefix' => $pathPrefix), - array('currentPath' => current_path()), - ), - 'type' => 'setting', - 'scope' => 'header', - 'group' => JS_SETTING, - 'every_page' => TRUE, - 'weight' => 0, - 'browsers' => array(), - ), - 'core/misc/drupal.js' => array( - 'data' => 'core/misc/drupal.js', - 'type' => 'file', - 'scope' => 'header', - 'group' => JS_LIBRARY, - 'every_page' => TRUE, - 'weight' => -1, - 'preprocess' => TRUE, - 'cache' => TRUE, - 'defer' => FALSE, - 'async' => FALSE, - 'browsers' => array(), - ), - ); - // Register all required libraries. - drupal_add_library('system', 'jquery', TRUE); - drupal_add_library('system', 'jquery.once', TRUE); - drupal_add_library('system', 'html5shiv', TRUE); - } - switch ($options['type']) { case 'setting': // All JavaScript settings are placed in the header of the page with @@ -3946,23 +3917,54 @@ function drupal_get_js($scope = 'header', $javascript = NULL, $skip_alter = FALS } } - // Sort the JavaScript so that it appears in the correct order. - uasort($items, 'drupal_sort_css_js'); + if (!empty($items)) { + // Sort the JavaScript files so that they appear in the correct order. + uasort($items, 'drupal_sort_css_js'); + // Don't add settings if there is no other JavaScript on the page, unless + // this is an ajax request. + if (!empty($items['settings']) || drupal_get_request_content_type() == 'ajax') { + global $theme_key; + // Provide the page with information about the theme that's used, so that a + // later AJAX request can be rendered using the same theme. + // @see ajax_base_page_theme() + $setting['ajaxPageState']['theme'] = $theme_key; + // Checks that the DB is available before filling theme_token. + if (!defined('MAINTENANCE_MODE')) { + $setting['ajaxPageState']['theme_token'] = drupal_get_token($theme_key); + } + + // Provide the page with information about the individual JavaScript files + // used, information not otherwise available when aggregation is enabled. + $setting['ajaxPageState']['js'] = array_fill_keys(array_keys($items), 1); + unset($setting['ajaxPageState']['js']['settings']); + + // Provide the page with information about the individual CSS files used, + // information not otherwise available when CSS aggregation is enabled. + // The setting is attached later in this function, but is set here, so + // that CSS files removed in drupal_process_attached() are still + // considered "used" and prevented from being added in a later AJAX + // request. + // Skip if no files were added to the page otherwise jQuery.extend() will + // overwrite the Drupal.settings.ajaxPageState.css object with an empty + // array. + $css = drupal_add_css(); + if (!empty($css)) { + // Cast the array to an object to be on the safe side even if not empty. + $setting['ajaxPageState']['css'] = (object) array_fill_keys(array_keys($css), 1); + } - // Provide the page with information about the individual JavaScript files - // used, information not otherwise available when aggregation is enabled. - $setting['ajaxPageState']['js'] = array_fill_keys(array_keys($items), 1); - unset($setting['ajaxPageState']['js']['settings']); - drupal_add_js($setting, 'setting'); + drupal_add_js($setting, 'setting'); - // If we're outputting the header scope, then this might be the final time - // that drupal_get_js() is running, so add the setting to this output as well - // as to the drupal_add_js() cache. If $items['settings'] doesn't exist, it's - // because drupal_get_js() was intentionally passed a $javascript argument - // stripped of settings, potentially in order to override how settings get - // output, so in this case, do not add the setting to this output. - if ($scope == 'header' && isset($items['settings'])) { - $items['settings']['data'][] = $setting; + // If we're outputting the header scope, then this might be the final time + // that drupal_get_js() is running, so add the settings to this output as well + // as to the drupal_add_js() cache. If $items['settings'] doesn't exist, it's + // because drupal_get_js() was intentionally passed a $javascript argument + // stripped of settings, potentially in order to override how settings get + // output, so in this case, do not add the setting to this output. + if ($scope == 'header' && isset($items['settings'])) { + $items['settings']['data'][] = $setting; + } + } } // Render the HTML needed to load the JavaScript. @@ -4228,7 +4230,7 @@ function drupal_aggregate_js(&$js_groups) { * are the attached data. For example: * @code * $build['#attached'] = array( - * 'js' => array(drupal_get_path('module', 'taxonomy') . '/taxonomy.js'), + * 'library' => array(array('taxonomy', 'taxonomy')), * 'css' => array(drupal_get_path('module', 'taxonomy') . '/taxonomy.css'), * ); * @endcode diff --git a/core/includes/form.inc b/core/includes/form.inc index 65ef9bc..cb4a6c5 100644 --- a/core/includes/form.inc +++ b/core/includes/form.inc @@ -3408,7 +3408,7 @@ function theme_tableselect($variables) { // checkboxes/radios in the first table column. if ($element['#js_select']) { // Add a "Select all" checkbox. - drupal_add_js('core/misc/tableselect.js'); + drupal_add_library('system', 'drupal.tableselect'); array_unshift($header, array('class' => array('select-all'))); } else { @@ -3597,7 +3597,7 @@ function form_process_machine_name($element, &$form_state) { ), ), ); - $element['#attached']['js'][] = 'core/misc/machine-name.js'; + $element['#attached']['library'][] = array('system', 'drupal.machine-name'); $element['#attached']['js'][] = $js_settings; return $element; diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc index edaf8ec..d9752fd 100644 --- a/core/includes/install.core.inc +++ b/core/includes/install.core.inc @@ -1525,9 +1525,9 @@ function install_configure_form($form, &$form_state, &$install_state) { drupal_set_message(st('All necessary changes to %dir and %file have been made, so you should remove write permissions to them now in order to avoid security risks. If you are unsure how to do so, consult the online handbook.', array('%dir' => $settings_dir, '%file' => $settings_file, '@handbook_url' => 'http://drupal.org/server-permissions')), 'warning'); } - drupal_add_js(drupal_get_path('module', 'system') . '/system.js'); + drupal_add_library('system', 'drupal.system'); // Add JavaScript time zone detection. - drupal_add_js('core/misc/timezone.js'); + drupal_add_library('system', 'drupal.timezone'); // We add these strings as settings because JavaScript translation does not // work on install time. drupal_add_js(array('copyFieldValue' => array('edit-site-mail' => array('edit-account-mail'))), 'setting'); diff --git a/core/includes/theme.inc b/core/includes/theme.inc index f807979..1806e81 100644 --- a/core/includes/theme.inc +++ b/core/includes/theme.inc @@ -93,15 +93,6 @@ function drupal_theme_initialize() { // Themes can have alter functions, so reset the drupal_alter() cache. drupal_static_reset('drupal_alter'); - - // Provide the page with information about the theme that's used, so that a - // later Ajax request can be rendered using the same theme. - // @see ajax_base_page_theme() - $setting['ajaxPageState'] = array( - 'theme' => $theme_key, - 'theme_token' => drupal_get_token($theme_key), - ); - drupal_add_js($setting, 'setting'); } /** @@ -649,7 +640,7 @@ function _theme_build_registry($theme, $base_theme, $theme_engine) { * their base theme), direct sub-themes of sub-themes, etc. The keys are * the themes' machine names, and the values are the themes' human-readable * names. This element is not set if there are no themes on the system that - * declare this theme as their base theme. + * declare this theme as their base theme. */ function list_themes($refresh = FALSE) { $list = &drupal_static(__FUNCTION__, array()); @@ -1841,7 +1832,7 @@ function theme_table($variables) { // Add sticky headers, if applicable. if (count($header) && $sticky) { - drupal_add_js('core/misc/tableheader.js'); + drupal_add_library('system', 'drupal.tableheader'); // Add 'sticky-enabled' class to the table to identify it for JS. // This is needed to target tables constructed by this function. $attributes['class'][] = 'sticky-enabled'; @@ -2603,6 +2594,7 @@ function template_process_page(&$variables) { * @see html.tpl.php */ function template_process_html(&$variables) { + drupal_add_library('system', 'html5shiv', TRUE); // Render page_top and page_bottom into top level variables. $variables['page_top'] = drupal_render($variables['page']['page_top']); $variables['page_bottom'] = drupal_render($variables['page']['page_bottom']); diff --git a/core/modules/block/block.admin.inc b/core/modules/block/block.admin.inc index aa018da..848298f 100644 --- a/core/modules/block/block.admin.inc +++ b/core/modules/block/block.admin.inc @@ -82,8 +82,8 @@ function block_admin_display_prepare_blocks($theme) { function block_admin_display_form($form, &$form_state, $blocks, $theme, $block_regions = NULL) { $path = drupal_get_path('module', 'block'); $form['#attached']['css'][] = $path . '/block.admin.css'; - $form['#attached']['js'][] = 'core/misc/tableheader.js'; - $form['#attached']['js'][] = $path . '/block.js'; + $form['#attached']['library'][] = array('system', 'drupal.tableheader'); + $form['#attached']['library'][] = array('block', 'drupal.block'); // Get a list of block regions if one was not provided. if (!isset($block_regions)) { @@ -346,7 +346,7 @@ function block_admin_configure($form, &$form_state, $module, $delta) { $form['visibility'] = array( '#type' => 'vertical_tabs', '#attached' => array( - 'js' => array(drupal_get_path('module', 'block') . '/block.js'), + 'library' => array(array('block', 'drupal.block')), ), ); diff --git a/core/modules/block/block.module b/core/modules/block/block.module index 2592137..0626c08 100644 --- a/core/modules/block/block.module +++ b/core/modules/block/block.module @@ -1085,3 +1085,22 @@ function block_language_delete($language) { ->condition('langcode', $language->langcode) ->execute(); } + +/** + * Implements hook_library_info(). + */ +function block_library_info() { + $libraries['drupal.block'] = array( + 'title' => 'Block', + 'version' => VERSION, + 'js' => array( + drupal_get_path('module', 'block') . '/block.js' => array(), + ), + 'dependencies' => array( + array('system', 'jquery'), + array('system', 'drupal'), + ), + ); + + return $libraries; +} diff --git a/core/modules/book/book.module b/core/modules/book/book.module index 9231082..ab3628c 100644 --- a/core/modules/book/book.module +++ b/core/modules/book/book.module @@ -544,7 +544,7 @@ function _book_add_form_elements(&$form, &$form_state, Node $node) { 'class' => array('book-outline-form'), ), '#attached' => array( - 'js' => array(drupal_get_path('module', 'book') . '/book.js'), + 'library' => array(array('book', 'drupal.book')), ), '#tree' => TRUE, ); @@ -1454,3 +1454,23 @@ function book_menu_subtree_data($link) { return $tree[$cid]; } + +/** + * Implements hook_library_info(). + */ +function book_library_info() { + $libraries['drupal.book'] = array( + 'title' => 'Book', + 'version' => VERSION, + 'js' => array( + drupal_get_path('module', 'book') . '/book.js' => array(), + ), + 'dependencies' => array( + array('system', 'jquery'), + array('system', 'drupal'), + array('system', 'drupal.form'), + ), + ); + + return $libraries; +} diff --git a/core/modules/color/color.module b/core/modules/color/color.module index b2b67a7..d4ca6ca 100644 --- a/core/modules/color/color.module +++ b/core/modules/color/color.module @@ -184,9 +184,8 @@ function color_scheme_form($complete_form, &$form_state, $theme) { '#options' => $color_sets, '#default_value' => $scheme_name, '#attached' => array( - // Add Farbtastic color picker. 'library' => array( - array('system', 'farbtastic'), + array('color', 'drupal.color'), ), // Add custom CSS. 'css' => array( @@ -194,7 +193,6 @@ function color_scheme_form($complete_form, &$form_state, $theme) { ), // Add custom JavaScript. 'js' => array( - $base . '/color.js', array( 'data' => array( 'color' => array( @@ -246,6 +244,7 @@ function theme_color_scheme_form($variables) { $path = drupal_get_path('theme', $theme) . '/'; drupal_add_css($path . $info['preview_css']); + // @todo Transform to add library. $preview_js_path = isset($info['preview_js']) ? $path . $info['preview_js'] : drupal_get_path('module', 'color') . '/' . 'preview.js'; // Add the JS at a weight below color.js. drupal_add_js($preview_js_path, array('weight' => -1)); @@ -744,3 +743,38 @@ function _color_rgb2hsl($rgb) { return array($h, $s, $l); } + +/** + * Implements hook_library_info(). + */ +function color_library_info() { + $libraries['drupal.color'] = array( + 'title' => 'Color', + 'version' => VERSION, + 'js' => array( + drupal_get_path('module', 'color') . '/color.js' => array(), + ), + 'dependencies' => array( + array('system', 'jquery'), + array('system', 'drupal'), + array('system', 'jquery.once'), + array('system', 'jquery.farbtastic'), + array('color', 'drupal.color.preview'), + ), + ); + $libraries['drupal.color.preview'] = array( + 'title' => 'Color preview', + 'version' => VERSION, + 'js' => array( + drupal_get_path('module', 'color') . '/preview.js' => array(), + ), + 'dependencies' => array( + array('system', 'jquery'), + array('system', 'drupal'), + array('system', 'drupal.settings'), + array('system', 'jquery.once'), + ), + ); + + return $libraries; +} diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module index 9f5b2cf..d3cec46 100644 --- a/core/modules/comment/comment.module +++ b/core/modules/comment/comment.module @@ -1183,7 +1183,7 @@ function comment_form_node_type_form_alter(&$form, $form_state) { 'class' => array('comment-node-type-settings-form'), ), '#attached' => array( - 'js' => array(drupal_get_path('module', 'comment') . '/comment-node-form.js'), + 'library' => array('comment', 'drupal.comment'), ), ); // Unlike coment_form_node_form_alter(), all of these settings are applied @@ -1261,8 +1261,8 @@ function comment_form_node_form_alter(&$form, $form_state) { 'class' => array('comment-node-settings-form'), ), '#attached' => array( - 'js' => array(drupal_get_path('module', 'comment') . '/comment-node-form.js'), - ), + 'library' => array('comment', 'drupal.comment'), + ), '#weight' => 30, ); $comment_count = isset($node->nid) ? db_query('SELECT comment_count FROM {node_comment_statistics} WHERE nid = :nid', array(':nid' => $node->nid))->fetchField() : 0; @@ -2145,3 +2145,23 @@ function comment_file_download_access($field, $entity_type, $entity) { return FALSE; } } + +/** + * Implements hook_library_info(). + */ +function comment_library_info() { + $libraries['drupal.comment'] = array( + 'title' => 'Comment', + 'version' => VERSION, + 'js' => array( + drupal_get_path('module', 'comment') . '/comment-node-form.js' => array(), + ), + 'dependencies' => array( + array('system', 'jquery'), + array('system', 'drupal'), + array('system', 'drupal.form'), + ), + ); + + return $libraries; +} diff --git a/core/modules/contextual/contextual.module b/core/modules/contextual/contextual.module index a09d09f..37b3a21 100644 --- a/core/modules/contextual/contextual.module +++ b/core/modules/contextual/contextual.module @@ -40,10 +40,10 @@ function contextual_permission() { */ function contextual_library_info() { $path = drupal_get_path('module', 'contextual'); - $libraries['contextual-links'] = array( + $libraries['drupal.contextual-links'] = array( 'title' => 'Contextual Links', 'website' => 'http://drupal.org/node/473268', - 'version' => '1.0', + 'version' => VERSION, 'js' => array( $path . '/contextual.js' => array(), ), @@ -51,7 +51,13 @@ function contextual_library_info() { $path . '/contextual.base.css' => array(), $path . '/contextual.theme.css' => array(), ), + 'dependencies' => array( + array('system', 'jquery'), + array('system', 'drupal'), + array('system', 'jquery.once'), + ), ); + return $libraries; } @@ -68,7 +74,7 @@ function contextual_element_info() { '#attributes' => array('class' => array('contextual-links')), '#attached' => array( 'library' => array( - array('contextual', 'contextual-links'), + array('contextual', 'drupal.contextual-links'), ), ), ); diff --git a/core/modules/field_ui/field_ui.admin.inc b/core/modules/field_ui/field_ui.admin.inc index 5871be0..0be7ffe 100644 --- a/core/modules/field_ui/field_ui.admin.inc +++ b/core/modules/field_ui/field_ui.admin.inc @@ -640,8 +640,7 @@ function field_ui_field_overview_form($form, &$form_state, $entity_type, $bundle $form['actions'] = array('#type' => 'actions'); $form['actions']['submit'] = array('#type' => 'submit', '#value' => t('Save')); - $form['#attached']['css'][] = drupal_get_path('module', 'field_ui') . '/field_ui.admin.css'; - $form['#attached']['js'][] = drupal_get_path('module', 'field_ui') . '/field_ui.js'; + $form['#attached']['library'][] = array('field_ui', 'drupal.field_ui'); // Add settings for the update selects behavior. $js_fields = array(); @@ -1228,8 +1227,7 @@ function field_ui_display_overview_form($form, &$form_state, $entity_type, $bund $form['actions'] = array('#type' => 'actions'); $form['actions']['submit'] = array('#type' => 'submit', '#value' => t('Save')); - $form['#attached']['js'][] = drupal_get_path('module', 'field_ui') . '/field_ui.js'; - $form['#attached']['css'][] = drupal_get_path('module', 'field_ui') . '/field_ui.admin.css'; + $form['#attached']['library'][] = array('field_ui', 'drupal.field_ui'); // Add tabledrag behavior. $form['#attached']['drupal_add_tabledrag'][] = array('field-display-overview', 'order', 'sibling', 'field-weight'); diff --git a/core/modules/field_ui/field_ui.module b/core/modules/field_ui/field_ui.module index 076cc23..bde3f35 100644 --- a/core/modules/field_ui/field_ui.module +++ b/core/modules/field_ui/field_ui.module @@ -380,3 +380,27 @@ function field_ui_form_node_type_form_submit($form, &$form_state) { $form_state['redirect'] = _field_ui_bundle_admin_path('node', $form_state['values']['type']) .'/fields'; } } + +/** + * Implements hook_library_info(). + */ +function field_ui_library_info() { + $libraries['drupal.field_ui'] = array( + 'title' => 'Field UI', + 'version' => VERSION, + 'js' => array( + drupal_get_path('module', 'field_ui') . '/field_ui.js' => array(), + ), + 'css' => array( + drupal_get_path('module', 'field_ui') . '/field_ui.admin.css' => array(), + ), + 'dependencies' => array( + array('system', 'jquery'), + array('system', 'drupal'), + array('system', 'drupal.settings'), + array('system', 'jquery.once'), + ), + ); + + return $libraries; +} diff --git a/core/modules/file/file.field.inc b/core/modules/file/file.field.inc index 70314db..cbc2246 100644 --- a/core/modules/file/file.field.inc +++ b/core/modules/file/file.field.inc @@ -37,7 +37,7 @@ function file_field_settings_form($field, $instance, $has_data) { $defaults = field_info_field_settings($field['type']); $settings = array_merge($defaults, $field['settings']); - $form['#attached']['js'][] = drupal_get_path('module', 'file') . '/file.js'; + $form['#attached']['library'][] = array('file', 'drupal.file'); $form['display_field'] = array( '#type' => 'checkbox', diff --git a/core/modules/file/file.module b/core/modules/file/file.module index 24dd94f..e202428 100644 --- a/core/modules/file/file.module +++ b/core/modules/file/file.module @@ -78,8 +78,7 @@ function file_element_info() { '#size' => 22, '#extended' => FALSE, '#attached' => array( - 'css' => array($file_path . '/file.admin.css'), - 'js' => array($file_path . '/file.js'), + 'library' => array(array('file','drupal.file')), ), ); return $types; @@ -1023,3 +1022,26 @@ function file_get_file_references(File $file, $field = NULL, $age = FIELD_LOAD_R /** * @} End of "defgroup file-module-api". */ + +/** + * Implements hook_library_info(). + */ +function file_library_info() { + $libraries['drupal.file'] = array( + 'title' => 'File', + 'version' => VERSION, + 'js' => array( + drupal_get_path('module', 'file') . '/file.js' => array(), + ), + 'css' => array( + drupal_get_path('module', 'file') . '/file.admin.css' + ), + 'dependencies' => array( + array('system', 'jquery'), + array('system', 'drupal'), + array('system', 'drupal.settings'), + ), + ); + + return $libraries; +} diff --git a/core/modules/filter/filter.admin.inc b/core/modules/filter/filter.admin.inc index 40a5eab..3a8138a 100644 --- a/core/modules/filter/filter.admin.inc +++ b/core/modules/filter/filter.admin.inc @@ -120,8 +120,7 @@ function filter_admin_format_form($form, &$form_state, $format) { $form['#format'] = $format; $form['#tree'] = TRUE; - $form['#attached']['js'][] = drupal_get_path('module', 'filter') . '/filter.admin.js'; - $form['#attached']['css'][] = drupal_get_path('module', 'filter') . '/filter.admin.css'; + $form['#attached']['library'][] = array('filter', 'drupal.filter.admin'); $form['name'] = array( '#type' => 'textfield', diff --git a/core/modules/filter/filter.module b/core/modules/filter/filter.module index 4d9bfef..62726d3 100644 --- a/core/modules/filter/filter.module +++ b/core/modules/filter/filter.module @@ -845,8 +845,7 @@ function filter_process_format($element) { // Turn original element into a text format wrapper. $path = drupal_get_path('module', 'filter'); - $element['#attached']['js'][] = $path . '/filter.js'; - $element['#attached']['css'][] = $path . '/filter.admin.css'; + $element['#attached']['library'][] = array('filter', 'drupal.filter'); // Setup child container for the text format widget. $element['format'] = array( @@ -1695,3 +1694,42 @@ function _filter_html_escape_tips($filter, $format, $long = FALSE) { /** * @} End of "defgroup standard_filters". */ + +/** + * Implements hook_library_info(). + */ +function filter_library_info() { + $libraries['drupal.filter.admin'] = array( + 'title' => 'Filter', + 'version' => VERSION, + 'js' => array( + drupal_get_path('module', 'filter') . '/filter.admin.js' => array(), + ), + 'css' => array( + drupal_get_path('module', 'filter') . '/filter.admin.css' + ), + 'dependencies' => array( + array('system', 'jquery'), + array('system', 'drupal'), + array('system', 'jquery.once'), + array('system', 'drupal.form'), + ), + ); + $libraries['drupal.filter'] = array( + 'title' => 'Filter', + 'version' => VERSION, + 'js' => array( + drupal_get_path('module', 'filter') . '/filter.js' => array(), + ), + 'css' => array( + drupal_get_path('module', 'filter') . '/filter.admin.css' + ), + 'dependencies' => array( + array('system', 'jquery'), + array('system', 'drupal'), + array('system', 'jquery.once'), + ), + ); + + return $libraries; +} diff --git a/core/modules/locale/locale.module b/core/modules/locale/locale.module index 525a339..de07bee 100644 --- a/core/modules/locale/locale.module +++ b/core/modules/locale/locale.module @@ -373,7 +373,7 @@ function locale_js_alter(&$javascript) { $files = $new_files = FALSE; foreach ($javascript as $item) { - if ($item['type'] == 'file') { + if (isset($item['type']) && $item['type'] == 'file') { $files = TRUE; $filepath = $item['data']; if (!in_array($filepath, $parsed)) { @@ -430,8 +430,7 @@ function locale_library_info_alter(&$libraries, $module) { // locale.datepicker.js should be added in the JS_LIBRARY group, so that // this attach behavior will execute early. JS_LIBRARY is the default for // hook_library_info_alter(), thus does not have to be specified explicitly. - $datepicker = drupal_get_path('module', 'locale') . '/locale.datepicker.js'; - $libraries['jquery.ui.datepicker']['js'][$datepicker] = array(); + $libraries['jquery.ui.datepicker']['dependencies'][] = array('locale', 'drupal.locale.datepicker'); $libraries['jquery.ui.datepicker']['js'][] = array( 'data' => array( 'jquery' => array( @@ -879,3 +878,35 @@ function _locale_rebuild_js($langcode = NULL) { return TRUE; } } + +/** + * Implements hook_library_info(). + */ +function locale_library_info() { + $libraries['drupal.locale.admin'] = array( + 'title' => 'Locale', + 'version' => VERSION, + 'js' => array( + drupal_get_path('module', 'locale') . '/locale.admin.js' => array(), + ), + 'dependencies' => array( + array('system', 'jquery'), + array('system', 'drupal'), + array('system', 'jquery.once'), + ), + ); + $libraries['drupal.locale.datepicker'] = array( + 'title' => 'Locale Datepicker UI', + 'version' => VERSION, + 'js' => array( + drupal_get_path('module', 'locale') . '/locale.datepicker.js' => array(), + ), + 'dependencies' => array( + array('system', 'jquery'), + array('system', 'drupal'), + array('system', 'drupal.settings'), + ), + ); + + return $libraries; +} diff --git a/core/modules/locale/locale.pages.inc b/core/modules/locale/locale.pages.inc index 539c382..d4a30fb 100644 --- a/core/modules/locale/locale.pages.inc +++ b/core/modules/locale/locale.pages.inc @@ -255,8 +255,8 @@ function locale_translate_edit_form($form, &$form_state) { $form['#attached']['css'] = array( $path . '/locale.admin.css', ); - $form['#attached']['js'] = array( - $path . '/locale.admin.js', + $form['#attached']['library'] = array( + array('locale', 'drupal.locale.admin') ); $form['langcode'] = array( diff --git a/core/modules/menu/menu.module b/core/modules/menu/menu.module index 653c17f..189abcc 100644 --- a/core/modules/menu/menu.module +++ b/core/modules/menu/menu.module @@ -650,7 +650,7 @@ function menu_form_node_form_alter(&$form, $form_state) { '#collapsed' => !$link['link_title'], '#group' => 'additional_settings', '#attached' => array( - 'js' => array(drupal_get_path('module', 'menu') . '/menu.js'), + 'library' => array(array('menu', 'drupal.menu')), ), '#tree' => TRUE, '#weight' => -2, @@ -755,7 +755,7 @@ function menu_form_node_type_form_alter(&$form, $form_state) { '#collapsible' => TRUE, '#collapsed' => TRUE, '#attached' => array( - 'js' => array(drupal_get_path('module', 'menu') . '/menu.admin.js'), + 'library' => array(array('menu', 'drupal.menu.admin')), ), '#group' => 'additional_settings', ); @@ -819,3 +819,34 @@ function menu_preprocess_block(&$variables) { $variables['attributes']['role'] = 'navigation'; } } + +/** + * Implements hook_library_info(). + */ +function menu_library_info() { + $libraries['drupal.menu'] = array( + 'title' => 'Menu', + 'version' => VERSION, + 'js' => array( + drupal_get_path('module', 'menu') . '/menu.js' => array(), + ), + 'dependencies' => array( + array('system', 'jquery'), + array('system', 'drupal'), + array('system', 'drupal.form'), + ), + ); + $libraries['drupal.menu.admin'] = array( + 'title' => 'Menu admin', + 'version' => VERSION, + 'js' => array( + drupal_get_path('module', 'menu') . '/menu.admin.js' => array(), + ), + 'dependencies' => array( + array('system', 'jquery'), + array('system', 'drupal'), + ), + ); + + return $libraries; +} diff --git a/core/modules/node/content_types.inc b/core/modules/node/content_types.inc index 88495f4..355a022 100644 --- a/core/modules/node/content_types.inc +++ b/core/modules/node/content_types.inc @@ -127,7 +127,7 @@ function node_type_form($form, &$form_state, $type = NULL) { $form['additional_settings'] = array( '#type' => 'vertical_tabs', '#attached' => array( - 'js' => array(drupal_get_path('module', 'node') . '/content_types.js'), + 'library' => array(array('node', 'drupal.content_types')), ), ); diff --git a/core/modules/node/node.admin.inc b/core/modules/node/node.admin.inc index 7aa16ec..465b2ba 100644 --- a/core/modules/node/node.admin.inc +++ b/core/modules/node/node.admin.inc @@ -222,7 +222,7 @@ function node_filter_form() { $form['filters']['status']['actions']['reset'] = array('#type' => 'submit', '#value' => t('Reset')); } - drupal_add_js('core/misc/form.js'); + $form['#attached']['library'][] = array('system', 'drupal.form'); return $form; } diff --git a/core/modules/node/node.module b/core/modules/node/node.module index cf10c07..d98985b 100644 --- a/core/modules/node/node.module +++ b/core/modules/node/node.module @@ -3995,3 +3995,36 @@ function node_language_delete($language) { ->condition('langcode', $language->langcode) ->execute(); } + +/** + * Implements hook_library_info(). + */ +function node_library_info() { + $libraries['drupal.node'] = array( + 'title' => 'Node', + 'version' => VERSION, + 'js' => array( + drupal_get_path('module', 'node') . '/node.js' => array(), + ), + 'dependencies' => array( + array('system', 'jquery'), + array('system', 'drupal'), + array('system', 'drupal.settings'), + array('system', 'drupal.form'), + ), + ); + $libraries['drupal.content_types'] = array( + 'title' => 'Content types', + 'version' => VERSION, + 'js' => array( + drupal_get_path('module', 'node') . '/content_types.js' => array(), + ), + 'dependencies' => array( + array('system', 'jquery'), + array('system', 'drupal'), + array('system', 'drupal.form'), + ), + ); + + return $libraries; +} diff --git a/core/modules/openid/openid.module b/core/modules/openid/openid.module index 5098216..5cbca61 100644 --- a/core/modules/openid/openid.module +++ b/core/modules/openid/openid.module @@ -134,9 +134,7 @@ function openid_form_user_login_alter(&$form, &$form_state) { } function _openid_user_login_form_alter(&$form, &$form_state) { - $form['#attached']['css'][] = drupal_get_path('module', 'openid') . '/openid.css'; - $form['#attached']['js'][] = drupal_get_path('module', 'openid') . '/openid.js'; - $form['#attached']['library'][] = array('system', 'jquery.cookie'); + $form['#attached']['library'][] = array('openid', 'drupal.openid'); if (!empty($form_state['input']['openid_identifier'])) { $form['name']['#required'] = FALSE; $form['pass']['#required'] = FALSE; @@ -1076,3 +1074,25 @@ function openid_cron() { ->condition('expires', REQUEST_TIME, '<') ->execute(); } + +/** + * Implements hook_library_info(). + */ +function openid_library_info() { + $libraries['openid'] = array( + 'title' => 'OpenID', + 'version' => VERSION, + 'js' => array( + drupal_get_path('module', 'openid') . '/openid.js' => array(), + ), + 'css' => array( + drupal_get_path('module', 'openid') . '/openid.css' => array(), + ), + 'dependencies' => array( + array('system', 'drupal'), + array('system', 'jquery.cookie') + ), + ); + + return $libraries; +} diff --git a/core/modules/overlay/overlay.module b/core/modules/overlay/overlay.module index 3aaed7d..7a07b70 100644 --- a/core/modules/overlay/overlay.module +++ b/core/modules/overlay/overlay.module @@ -200,7 +200,7 @@ function overlay_library_info() { $module_path = drupal_get_path('module', 'overlay'); // Overlay parent. - $libraries['parent'] = array( + $libraries['drupal.overlay.parent'] = array( 'title' => 'Overlay: Parent', 'website' => 'http://drupal.org/documentation/modules/overlay', 'version' => '1.0', @@ -211,12 +211,15 @@ function overlay_library_info() { $module_path . '/overlay-parent.css' => array(), ), 'dependencies' => array( + array('system', 'jquery'), + array('system', 'drupal'), + array('system', 'drupal.settings'), array('system', 'jquery.ui.core'), array('system', 'jquery.bbq'), ), ); // Overlay child. - $libraries['child'] = array( + $libraries['drupal.overlay.child'] = array( 'title' => 'Overlay: Child', 'website' => 'http://drupal.org/documentation/modules/overlay', 'version' => '1.0', @@ -226,6 +229,12 @@ function overlay_library_info() { 'css' => array( $module_path . '/overlay-child.css' => array(), ), + 'dependencies' => array( + array('system', 'jquery'), + array('system', 'drupal'), + array('system', 'drupal.settings'), + array('system', 'jquery.once'), + ), ); return $libraries; diff --git a/core/modules/path/path.module b/core/modules/path/path.module index 2baa603..02a0490 100644 --- a/core/modules/path/path.module +++ b/core/modules/path/path.module @@ -129,7 +129,7 @@ function path_form_node_form_alter(&$form, $form_state) { 'class' => array('path-form'), ), '#attached' => array( - 'js' => array(drupal_get_path('module', 'path') . '/path.js'), + 'library' => array(array('path', 'drupal.path')), ), '#access' => user_access('create url aliases') || user_access('administer url aliases'), '#weight' => 30, @@ -314,3 +314,23 @@ function path_taxonomy_term_delete(Term $term) { // Delete all aliases associated with this term. path_delete(array('source' => 'taxonomy/term/' . $term->tid)); } + +/** + * Implements hook_library_info(). + */ +function path_library_info() { + $libraries['drupal.path'] = array( + 'title' => 'Path', + 'version' => VERSION, + 'js' => array( + drupal_get_path('module', 'path') . '/path.js' => array(), + ), + 'dependencies' => array( + array('system', 'jquery'), + array('system', 'drupal'), + array('system', 'drupal.form'), + ), + ); + + return $libraries; +} diff --git a/core/modules/shortcut/shortcut.admin.inc b/core/modules/shortcut/shortcut.admin.inc index 3345c59..26bdc36 100644 --- a/core/modules/shortcut/shortcut.admin.inc +++ b/core/modules/shortcut/shortcut.admin.inc @@ -73,7 +73,7 @@ function shortcut_set_switch($form, &$form_state, $account = NULL) { } $form['#attached'] = array( - 'js' => array(drupal_get_path('module', 'shortcut') . '/shortcut.admin.js'), + 'library' => array(array('shortcut', 'drupal.shortcut.admin')), ); $form['actions'] = array('#type' => 'actions'); diff --git a/core/modules/shortcut/shortcut.module b/core/modules/shortcut/shortcut.module index 27eb8c2..a548fc2 100644 --- a/core/modules/shortcut/shortcut.module +++ b/core/modules/shortcut/shortcut.module @@ -766,3 +766,21 @@ function shortcut_set_title($shortcut_set) { return $shortcut_set->title; } +/** + * Implements hook_library_info(). + */ +function shortcut_library_info() { + $libraries['drupal.shortcut.admin'] = array( + 'title' => 'Shortcut', + 'version' => VERSION, + 'js' => array( + drupal_get_path('module', 'shortcut') . '/shortcut.admin.js' => array(), + ), + 'dependencies' => array( + array('system', 'jquery'), + array('system', 'drupal'), + ), + ); + + return $libraries; +} diff --git a/core/modules/simpletest/simpletest.module b/core/modules/simpletest/simpletest.module index 4138916..44cbd83 100644 --- a/core/modules/simpletest/simpletest.module +++ b/core/modules/simpletest/simpletest.module @@ -566,3 +566,25 @@ function simpletest_mail_alter(&$message) { $message['send'] = FALSE; } } + +function simpletest_library_info() { + $libraries['drupal.simpletest'] = array( + 'title' => 'Simpletest', + 'version' => VERSION, + 'js' => array( + drupal_get_path('module', 'simpletest') . '/simpletest.js' => array(), + ), + 'css' => array( + drupal_get_path('module', 'simpletest') . '/simpletest.css' => array(), + ), + 'dependencies' => array( + array('system', 'jquery'), + array('system', 'drupal'), + array('system', 'drupal.settings'), + array('system', 'jquery.once'), + array('system', 'drupal.tableselect'), + ), + ); + + return $libraries; +} diff --git a/core/modules/simpletest/simpletest.pages.inc b/core/modules/simpletest/simpletest.pages.inc index a98b445..48cb3a1 100644 --- a/core/modules/simpletest/simpletest.pages.inc +++ b/core/modules/simpletest/simpletest.pages.inc @@ -68,9 +68,7 @@ function simpletest_test_form($form) { function theme_simpletest_test_table($variables) { $table = $variables['table']; - drupal_add_css(drupal_get_path('module', 'simpletest') . '/simpletest.css'); - drupal_add_js(drupal_get_path('module', 'simpletest') . '/simpletest.js'); - drupal_add_js('core/misc/tableselect.js'); + drupal_add_library('simpletest', 'drupal.simpletest'); // Create header for test selection table. $header = array( diff --git a/core/modules/statistics/statistics.module b/core/modules/statistics/statistics.module index 35f625a..56e48f4 100644 --- a/core/modules/statistics/statistics.module +++ b/core/modules/statistics/statistics.module @@ -103,10 +103,8 @@ function statistics_permission() { */ function statistics_node_view(Node $node, $view_mode) { if (!empty($node->nid) && $view_mode == 'full') { - $node->content['#attached']['js'] = array( - drupal_get_path('module', 'statistics') . '/statistics.js' => array( - 'scope' => 'footer' - ), + $node->content['#attached']['library'] = array( + array('statistics', 'drupal.statistics'), ); $settings = array('nid' => $node->nid); $node->content['#attached']['js'][] = array( @@ -462,3 +460,23 @@ function statistics_preprocess_block(&$variables) { $variables['attributes']['role'] = 'navigation'; } } + +/** + * Implements hook_library_info(). + */ +function statistics_library_info() { + $libraries['drupal.statistics'] = array( + 'title' => 'Statistics', + 'version' => VERSION, + 'js' => array( + drupal_get_path('module', 'statistics') . '/statistics.js' => array(), + ), + 'dependencies' => array( + array('system', 'jquery'), + array('system', 'drupal'), + array('system', 'drupal.settings'), + ), + ); + + return $libraries; +} diff --git a/core/modules/system/lib/Drupal/system/Tests/Common/JavaScriptTest.php b/core/modules/system/lib/Drupal/system/Tests/Common/JavaScriptTest.php index 1b07174..cfb82f6 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Common/JavaScriptTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Common/JavaScriptTest.php @@ -68,13 +68,7 @@ class JavaScriptTest extends WebTestBase { */ function testAddFile() { $javascript = drupal_add_js('core/misc/collapse.js'); - $this->assertTrue(array_key_exists('core/misc/jquery.js', $javascript), t('jQuery is added when a file is added.')); - $this->assertTrue(array_key_exists('core/misc/drupal.js', $javascript), t('Drupal.js is added when file is added.')); - $this->assertTrue(array_key_exists('core/misc/html5.js', $javascript), t('html5.js is added when file is added.')); $this->assertTrue(array_key_exists('core/misc/collapse.js', $javascript), t('JavaScript files are correctly added.')); - $this->assertEqual(base_path(), $javascript['settings']['data'][0]['basePath'], t('Base path JavaScript setting is correctly set.')); - $this->assertIdentical($GLOBALS['script_path'], $javascript['settings']['data'][1]['scriptPath'], t('Script path JavaScript setting is correctly set.')); - $this->assertIdentical('', $javascript['settings']['data'][2]['pathPrefix'], t('Path prefix JavaScript setting is correctly set.')); } /** @@ -82,7 +76,8 @@ class JavaScriptTest extends WebTestBase { */ function testAddSetting() { // Add a file in order to test default settings. - $javascript = drupal_add_js('core/misc/collapse.js'); + drupal_add_library('system', 'drupal.settings'); + $javascript = drupal_add_js(); $last_settings = end($javascript['settings']['data']); $this->assertTrue($last_settings['currentPath'], 'The current path JavaScript setting is set correctly.'); @@ -107,6 +102,7 @@ class JavaScriptTest extends WebTestBase { function testAsyncAttribute() { $default_query_string = variable_get('css_js_query_string', '0'); + drupal_add_library('system', 'drupal'); drupal_add_js('http://example.com/script.js', array('async' => TRUE)); drupal_add_js('core/misc/collapse.js', array('async' => TRUE)); $javascript = drupal_get_js(); @@ -124,6 +120,7 @@ class JavaScriptTest extends WebTestBase { function testDeferAttribute() { $default_query_string = variable_get('css_js_query_string', '0'); + drupal_add_library('system', 'drupal'); drupal_add_js('http://example.com/script.js', array('defer' => TRUE)); drupal_add_js('core/misc/collapse.js', array('defer' => TRUE)); $javascript = drupal_get_js(); @@ -139,6 +136,7 @@ class JavaScriptTest extends WebTestBase { * Test drupal_get_js() for JavaScript settings. */ function testHeaderSetting() { + drupal_add_library('system', 'drupal.settings'); // Only the second of these two entries should appear in Drupal.settings. drupal_add_js(array('commonTest' => 'commonTestShouldNotAppear'), 'setting'); drupal_add_js(array('commonTest' => 'commonTestShouldAppear'), 'setting'); @@ -183,6 +181,7 @@ class JavaScriptTest extends WebTestBase { * Test to see if resetting the JavaScript empties the cache. */ function testReset() { + drupal_add_library('system', 'drupal'); drupal_add_js('core/misc/collapse.js'); drupal_static_reset('drupal_add_js'); $this->assertEqual(array(), drupal_add_js(), t('Resetting the JavaScript correctly empties the cache.')); @@ -192,6 +191,7 @@ class JavaScriptTest extends WebTestBase { * Test adding inline scripts. */ function testAddInline() { + drupal_add_library('system', 'drupal'); $inline = 'jQuery(function () { });'; $javascript = drupal_add_js($inline, array('type' => 'inline', 'scope' => 'footer')); $this->assertTrue(array_key_exists('core/misc/jquery.js', $javascript), t('jQuery is added when inline scripts are added.')); @@ -203,6 +203,7 @@ class JavaScriptTest extends WebTestBase { * Test rendering an external JavaScript file. */ function testRenderExternal() { + drupal_add_library('system', 'drupal'); $external = 'http://example.com/example.js'; drupal_add_js($external, 'external'); $javascript = drupal_get_js(); @@ -214,6 +215,7 @@ class JavaScriptTest extends WebTestBase { * Test drupal_get_js() with a footer scope. */ function testFooterHTML() { + drupal_add_library('system', 'drupal'); $inline = 'jQuery(function () { });'; drupal_add_js($inline, array('type' => 'inline', 'scope' => 'footer')); $javascript = drupal_get_js('footer'); @@ -224,6 +226,7 @@ class JavaScriptTest extends WebTestBase { * Test drupal_add_js() sets preproccess to false when cache is set to false. */ function testNoCache() { + drupal_add_library('system', 'drupal'); $javascript = drupal_add_js('core/misc/collapse.js', array('cache' => FALSE)); $this->assertFalse($javascript['core/misc/collapse.js']['preprocess'], t('Setting cache to FALSE sets proprocess to FALSE when adding JavaScript.')); } @@ -232,6 +235,7 @@ class JavaScriptTest extends WebTestBase { * Test adding a JavaScript file with a different group. */ function testDifferentGroup() { + drupal_add_library('system', 'drupal'); $javascript = drupal_add_js('core/misc/collapse.js', array('group' => JS_THEME)); $this->assertEqual($javascript['core/misc/collapse.js']['group'], JS_THEME, t('Adding a JavaScript file with a different group caches the given group.')); } @@ -252,6 +256,7 @@ class JavaScriptTest extends WebTestBase { function testBrowserConditionalComments() { $default_query_string = variable_get('css_js_query_string', '0'); + drupal_add_library('system', 'drupal'); drupal_add_js('core/misc/collapse.js', array('browsers' => array('IE' => 'lte IE 8', '!IE' => FALSE))); drupal_add_js('jQuery(function () { });', array('type' => 'inline', 'browsers' => array('IE' => FALSE))); $javascript = drupal_get_js(); @@ -267,6 +272,7 @@ class JavaScriptTest extends WebTestBase { * Test JavaScript versioning. */ function testVersionQueryString() { + drupal_add_library('system', 'drupal'); drupal_add_js('core/misc/collapse.js', array('version' => 'foo')); drupal_add_js('core/misc/ajax.js', array('version' => 'bar')); $javascript = drupal_get_js(); @@ -283,6 +289,7 @@ class JavaScriptTest extends WebTestBase { // ahead of ones without. The order of JavaScript execution must be the // same regardless of whether aggregation is enabled, so ensure this // expected order, first with aggregation off. + drupal_add_library('system', 'drupal'); drupal_add_js('core/misc/ajax.js'); drupal_add_js('core/misc/collapse.js', array('every_page' => TRUE)); drupal_add_js('core/misc/autocomplete.js'); @@ -302,6 +309,7 @@ class JavaScriptTest extends WebTestBase { $config = config('system.performance'); $config->set('preprocess_js', 1); $config->save(); + drupal_add_library('system', 'drupal'); drupal_add_js('core/misc/ajax.js'); drupal_add_js('core/misc/collapse.js', array('every_page' => TRUE)); drupal_add_js('core/misc/autocomplete.js'); @@ -312,7 +320,7 @@ class JavaScriptTest extends WebTestBase { '', '', )); - $this->assertTrue(strpos($javascript, $expected) > 0, t('JavaScript is aggregated in the expected groups and order.')); + $this->assertTrue(strpos($javascript, $expected) !== FALSE, t('JavaScript is aggregated in the expected groups and order.')); } /** @@ -324,6 +332,7 @@ class JavaScriptTest extends WebTestBase { drupal_static_reset('drupal_add_js'); // Add two JavaScript files to the current request and build the cache. + drupal_add_library('system', 'drupal'); drupal_add_js('core/misc/ajax.js'); drupal_add_js('core/misc/autocomplete.js'); @@ -340,6 +349,7 @@ class JavaScriptTest extends WebTestBase { // Reset variables and add a file in a different scope first. variable_del('drupal_js_cache_files'); drupal_static_reset('drupal_add_js'); + drupal_add_library('system', 'drupal'); drupal_add_js('some/custom/javascript_file.js', array('scope' => 'footer')); drupal_add_js('core/misc/ajax.js'); drupal_add_js('core/misc/autocomplete.js'); @@ -406,6 +416,7 @@ class JavaScriptTest extends WebTestBase { // JavaScript files are sorted first by group, then by the 'every_page' // flag, then by weight (see drupal_sort_css_js()), so to test the effect of // weight, we need the other two options to be the same. + drupal_add_library('system', 'jquery'); drupal_add_js('core/misc/collapse.js', array('group' => JS_LIBRARY, 'every_page' => TRUE, 'weight' => -21)); $javascript = drupal_get_js(); $this->assertTrue(strpos($javascript, 'core/misc/collapse.js') < strpos($javascript, 'core/misc/jquery.js'), t('Rendering a JavaScript file above jQuery.')); @@ -432,7 +443,7 @@ class JavaScriptTest extends WebTestBase { * Adds a library to the page and tests for both its JavaScript and its CSS. */ function testLibraryRender() { - $result = drupal_add_library('system', 'farbtastic'); + $result = drupal_add_library('system', 'jquery.farbtastic'); $this->assertTrue($result !== FALSE, t('Library was added without errors.')); $scripts = drupal_get_js(); $styles = drupal_get_css(); @@ -447,11 +458,11 @@ class JavaScriptTest extends WebTestBase { */ function testLibraryAlter() { // Verify that common_test altered the title of Farbtastic. - $library = drupal_get_library('system', 'farbtastic'); + $library = drupal_get_library('system', 'jquery.farbtastic'); $this->assertEqual($library['title'], 'Farbtastic: Altered Library', t('Registered libraries were altered.')); // common_test_library_info_alter() also added a dependency on jQuery Form. - drupal_add_library('system', 'farbtastic'); + drupal_add_library('system', 'jquery.farbtastic'); $scripts = drupal_get_js(); $this->assertTrue(strpos($scripts, 'core/misc/jquery.form.js'), t('Altered library dependencies are added to the page.')); } @@ -462,7 +473,7 @@ class JavaScriptTest extends WebTestBase { * @see common_test_library_info() */ function testLibraryNameConflicts() { - $farbtastic = drupal_get_library('common_test', 'farbtastic'); + $farbtastic = drupal_get_library('common_test', 'jquery.farbtastic'); $this->assertEqual($farbtastic['title'], 'Custom Farbtastic Library', t('Alternative libraries can be added to the page.')); } @@ -484,7 +495,7 @@ class JavaScriptTest extends WebTestBase { * Tests the addition of libraries through the #attached['library'] property. */ function testAttachedLibrary() { - $element['#attached']['library'][] = array('system', 'farbtastic'); + $element['#attached']['library'][] = array('system', 'jquery.farbtastic'); drupal_render($element); $scripts = drupal_get_js(); $this->assertTrue(strpos($scripts, 'core/misc/farbtastic/farbtastic.js'), t('The attached_library property adds the additional libraries.')); @@ -496,14 +507,14 @@ class JavaScriptTest extends WebTestBase { function testGetLibrary() { // Retrieve all libraries registered by a module. $libraries = drupal_get_library('common_test'); - $this->assertTrue(isset($libraries['farbtastic']), t('Retrieved all module libraries.')); + $this->assertTrue(isset($libraries['jquery.farbtastic']), t('Retrieved all module libraries.')); // Retrieve all libraries for a module not implementing hook_library_info(). - // Note: This test installs Locale module. - $libraries = drupal_get_library('locale'); + // Note: This test installs language module. + $libraries = drupal_get_library('language'); $this->assertEqual($libraries, array(), t('Retrieving libraries from a module not implementing hook_library_info() returns an emtpy array.')); // Retrieve a specific library by module and name. - $farbtastic = drupal_get_library('common_test', 'farbtastic'); + $farbtastic = drupal_get_library('common_test', 'jquery.farbtastic'); $this->assertEqual($farbtastic['version'], '5.3', t('Retrieved a single library.')); // Retrieve a non-existing library by module and name. $farbtastic = drupal_get_library('common_test', 'foo'); diff --git a/core/modules/system/system.admin.inc b/core/modules/system/system.admin.inc index 8aa3ed4..f4f4b5a 100644 --- a/core/modules/system/system.admin.inc +++ b/core/modules/system/system.admin.inc @@ -1696,7 +1696,7 @@ function system_logging_settings_submit($form, &$form_state) { * @see system_performance_settings_submit(). */ function system_performance_settings($form, &$form_state) { - drupal_add_js(drupal_get_path('module', 'system') . '/system.js'); + drupal_add_library('system', 'drupal.system'); $config = config('system.performance'); $form['clear_cache'] = array( @@ -2886,7 +2886,8 @@ function system_configure_date_formats_form($form, &$form_state, $dfid = 0) { '#default_value' => ($dfid ? $format->format : ''), '#field_suffix' => ' ' . $now . '', '#attached' => array( - 'js' => array(drupal_get_path('module', 'system') . '/system.js', $js_settings), + 'library' => array(array('system', 'drupal.system')), + 'js' => array($js_settings), ), '#required' => TRUE, ); diff --git a/core/modules/system/system.module b/core/modules/system/system.module index 3c434ae..2adc714 100644 --- a/core/modules/system/system.module +++ b/core/modules/system/system.module @@ -1212,6 +1212,51 @@ function _system_batch_theme() { * Implements hook_library_info(). */ function system_library_info() { + // Drupal specific JavaScript. + $libraries['drupal'] = array( + 'title' => 'Drupal', + 'version' => VERSION, + 'js' => array( + 'core/misc/drupal.js' => array('group' => JS_LIBRARY, 'weight' => -18), + ), + 'dependencies' => array( + array('system', 'jquery'), + ), + ); + + // url() generates the script and prefix using hook_url_outbound_alter(). + // Instead of running the hook_url_outbound_alter() again here, extract + // them from url(). + // @todo Make this less hacky: http://drupal.org/node/1547376. + $scriptPath = $GLOBALS['script_path']; + $pathPrefix = ''; + url('', array('script' => &$scriptPath, 'prefix' => &$pathPrefix)); + // Drupal settings. + $libraries['drupal.settings'] = array( + 'title' => 'Drupal Settings', + 'version' => VERSION, + 'js' => array( + array( + 'data' => array( + 'basePath' => base_path(), + 'scriptPath' => $scriptPath, + 'pathPrefix' => $pathPrefix, + 'currentPath' => current_path(), + ), + 'type' => 'setting', + 'scope' => 'header', + 'group' => JS_SETTING, + 'every_page' => TRUE, + 'weight' => 0, + 'browsers' => array(), + ), + ), + 'dependencies' => array( + array('system', 'jquery'), + array('system', 'drupal'), + ), + ); + // Drupal's Ajax framework. $libraries['drupal.ajax'] = array( 'title' => 'Drupal AJAX', @@ -1221,6 +1266,9 @@ function system_library_info() { 'core/misc/ajax.js' => array('group' => JS_LIBRARY, 'weight' => 2), ), 'dependencies' => array( + array('system', 'jquery'), + array('system', 'drupal'), + array('system', 'drupal.settings'), array('system', 'drupal.progress'), ), ); @@ -1233,7 +1281,11 @@ function system_library_info() { 'core/misc/batch.js' => array('group' => JS_DEFAULT, 'cache' => FALSE), ), 'dependencies' => array( + array('system', 'jquery'), + array('system', 'drupal'), + array('system', 'drupal.settings'), array('system', 'drupal.progress'), + array('system', 'jquery.once'), ), ); @@ -1244,6 +1296,11 @@ function system_library_info() { 'js' => array( 'core/misc/progress.js' => array('group' => JS_DEFAULT), ), + 'dependencies' => array( + array('system', 'drupal'), + array('system', 'jquery'), + array('system', 'drupal.settings'), + ), ); // Drupal's form library. @@ -1253,6 +1310,12 @@ function system_library_info() { 'js' => array( 'core/misc/form.js' => array('group' => JS_LIBRARY, 'weight' => 1), ), + 'dependencies' => array( + array('system', 'jquery'), + array('system', 'drupal'), + array('system', 'jquery.cookie'), + array('system', 'jquery.once'), + ), ); // Drupal's states library. @@ -1262,6 +1325,12 @@ function system_library_info() { 'js' => array( 'core/misc/states.js' => array('group' => JS_LIBRARY, 'weight' => 1), ), + 'dependencies' => array( + array('system', 'jquery'), + array('system', 'drupal'), + array('system', 'drupal.settings'), + array('system', 'jquery.once'), + ), ); // Drupal's tabledrag library. @@ -1272,6 +1341,10 @@ function system_library_info() { 'core/misc/tabledrag.js' => array('group' => JS_LIBRARY, 'weight' => -1), ), 'dependencies' => array( + array('system', 'jquery'), + array('system', 'drupal'), + array('system', 'drupal.settings'), + array('system', 'jquery.once'), array('system', 'jquery.cookie'), ), ); @@ -1284,6 +1357,8 @@ function system_library_info() { 'core/misc/collapse.js' => array('group' => JS_DEFAULT), ), 'dependencies' => array( + array('system', 'jquery'), + array('system', 'drupal'), // collapse.js relies on drupalGetSummary in form.js array('system', 'drupal.form'), ), @@ -1296,6 +1371,11 @@ function system_library_info() { 'js' => array( 'core/misc/autocomplete.js' => array('group' => JS_DEFAULT), ), + 'dependencies' => array( + array('system', 'jquery'), + array('system', 'drupal'), + array('system', 'drupal.ajax'), + ), ); // jQuery. @@ -1316,6 +1396,9 @@ function system_library_info() { 'js' => array( 'core/misc/jquery.once.js' => array('group' => JS_LIBRARY, 'weight' => -19), ), + 'dependencies' => array( + array('system', 'jquery'), + ), ); // jQuery Form Plugin. @@ -1327,6 +1410,7 @@ function system_library_info() { 'core/misc/jquery.form.js' => array(), ), 'dependencies' => array( + array('system', 'jquery'), array('system', 'jquery.cookie'), ), ); @@ -1339,6 +1423,9 @@ function system_library_info() { 'js' => array( 'core/misc/jquery.ba-bbq.js' => array(), ), + 'dependencies' => array( + array('system', 'jquery'), + ), ); // Vertical Tabs. @@ -1353,13 +1440,16 @@ function system_library_info() { 'core/misc/vertical-tabs.css' => array(), ), 'dependencies' => array( + array('system', 'jquery'), + array('system', 'drupal'), + array('system', 'drupal.settings'), // Vertical tabs relies on drupalGetSummary in form.js array('system', 'drupal.form'), ), ); // Farbtastic. - $libraries['farbtastic'] = array( + $libraries['jquery.farbtastic'] = array( 'title' => 'Farbtastic', 'website' => 'http://code.google.com/p/farbtastic/', 'version' => '1.2', @@ -1397,6 +1487,9 @@ function system_library_info() { 'core/misc/ui/themes/base/jquery.ui.core.css' => array(), 'core/misc/ui/themes/base/jquery.ui.theme.css' => array(), ), + 'dependencies' => array( + array('system', 'jquery'), + ), ); $libraries['jquery.ui.accordion'] = array( 'title' => 'jQuery UI: Accordion', @@ -1831,12 +1924,109 @@ function system_library_info() { 'js' => array( 'core/misc/ui/external/jquery.cookie.js' => array(), ), + 'dependencies' => array( + array('system', 'jquery'), + ), + ); + + $libraries['drupal.tableselect'] = array( + 'title' => 'Tableselect', + 'version' => VERSION, + 'js' => array( + 'core/misc/tableselect.js' => array(), + ), + 'dependencies' => array( + array('system', 'drupal'), + array('system', 'jquery'), + ), + ); + $libraries['drupal.tableheader'] = array( + 'title' => 'Table header', + 'version' => VERSION, + 'js' => array( + 'core/misc/tableheader.js' => array(), + ), + 'dependencies' => array( + array('system', 'jquery'), + array('system', 'drupal'), + array('system', 'drupal.settings'), + array('system', 'jquery.once'), + ), + ); + $libraries['drupal.timezone'] = array( + 'title' => 'Timezone', + 'version' => VERSION, + 'js' => array( + 'core/misc/timezone.js' => array(), + ), + 'dependencies' => array( + array('system', 'jquery'), + array('system', 'drupal'), + ), + ); + $libraries['drupal.machine-name'] = array( + 'title' => 'Machine name', + 'version' => VERSION, + 'js' => array( + 'core/misc/machine-name.js' => array(), + ), + 'dependencies' => array( + array('system', 'jquery'), + array('system', 'drupal'), + array('system', 'drupal.settings'), + ), + ); + + $libraries['drupal.system'] = array( + 'title' => 'System', + 'version' => VERSION, + 'js' => array( + drupal_get_path('module', 'system') . '/system.js' => array(), + ), + 'dependencies' => array( + array('system', 'jquery'), + array('system', 'drupal'), + array('system', 'drupal.settings'), + ), + ); + $libraries['drupal.system.cron'] = array( + 'title' => 'System cron', + 'version' => VERSION, + 'js' => array( + drupal_get_path('module', 'system') . '/system.cron.js' => array(), + ), + 'dependencies' => array( + array('system', 'jquery'), + array('system', 'drupal'), + array('system', 'drupal.settings'), + array('system', 'jquery.once'), + ), ); return $libraries; } /** + * Implements hook_js_alter(). + */ +function system_js_alter(&$javascript) { + // Add configuration only if there are settings added to the page. This is + // only necessary for JavaScript that is added through drupal_add_js(), + // JavaScript that is added as a library would nominate its dependency on + // drupal.settings. + if (!empty($javascript['settings'])) { + $javascript['settings'] += array( + 'type' => 'setting', + 'scope' => 'header', + 'group' => JS_SETTING, + 'every_page' => TRUE, + 'weight' => 0, + 'browsers' => array(), + ); + } +} + +/** * Implements hook_stream_wrappers(). */ function system_stream_wrappers() { @@ -2272,7 +2462,7 @@ function system_user_timezone(&$form, &$form_state) { if (!isset($account->timezone) && $account->uid == $user->uid && empty($form_state['input']['timezone'])) { $form['timezone']['#description'] = t('Your time zone setting will be automatically detected if possible. Confirm the selection and click save.'); $form['timezone']['timezone']['#attributes'] = array('class' => array('timezone-detect')); - drupal_add_js('core/misc/timezone.js'); + drupal_add_library('system', 'drupal.timezone'); } } diff --git a/core/modules/system/tests/modules/common_test/common_test.module b/core/modules/system/tests/modules/common_test/common_test.module index 187fee5..65fcc8a 100644 --- a/core/modules/system/tests/modules/common_test/common_test.module +++ b/core/modules/system/tests/modules/common_test/common_test.module @@ -237,11 +237,11 @@ function theme_common_test_foo($variables) { * Implements hook_library_info_alter(). */ function common_test_library_info_alter(&$libraries, $module) { - if ($module == 'system' && isset($libraries['farbtastic'])) { + if ($module == 'system' && isset($libraries['jquery.farbtastic'])) { // Change the title of Farbtastic to "Farbtastic: Altered Library". - $libraries['farbtastic']['title'] = 'Farbtastic: Altered Library'; + $libraries['jquery.farbtastic']['title'] = 'Farbtastic: Altered Library'; // Make Farbtastic depend on jQuery Form to test library dependencies. - $libraries['farbtastic']['dependencies'][] = array('system', 'jquery.form'); + $libraries['jquery.farbtastic']['dependencies'][] = array('system', 'jquery.form'); } } @@ -251,7 +251,7 @@ function common_test_library_info_alter(&$libraries, $module) { * Adds Farbtastic in a different version. */ function common_test_library_info() { - $libraries['farbtastic'] = array( + $libraries['jquery.farbtastic'] = array( 'title' => 'Custom Farbtastic Library', 'website' => 'http://code.google.com/p/farbtastic/', 'version' => '5.3', @@ -261,6 +261,9 @@ function common_test_library_info() { 'css' => array( 'core/misc/farbtastic/farbtastic.css' => array(), ), + 'dependencies' => array( + array('system', 'jquery'), + ), ); return $libraries; } @@ -269,6 +272,7 @@ function common_test_library_info() { * Adds a JavaScript file and a CSS file with a query string appended. */ function common_test_js_and_css_querystring() { + drupal_add_library('system', 'drupal.settings'); drupal_add_js(drupal_get_path('module', 'node') . '/node.js'); drupal_add_css(drupal_get_path('module', 'node') . '/node.admin.css'); // A relative URI may have a query string. diff --git a/core/modules/taxonomy/taxonomy.admin.inc b/core/modules/taxonomy/taxonomy.admin.inc index 0065bbd..d8158f1 100644 --- a/core/modules/taxonomy/taxonomy.admin.inc +++ b/core/modules/taxonomy/taxonomy.admin.inc @@ -447,9 +447,8 @@ function theme_taxonomy_overview_terms($variables) { if ($form['#parent_fields']) { drupal_add_tabledrag('taxonomy', 'match', 'parent', 'term-parent', 'term-parent', 'term-id', FALSE); drupal_add_tabledrag('taxonomy', 'depth', 'group', 'term-depth', NULL, NULL, FALSE); - drupal_add_js(drupal_get_path('module', 'taxonomy') . '/taxonomy.js'); + drupal_add_library('taxonomy', 'drupal.taxonomy'); drupal_add_js(array('taxonomy' => array('backStep' => $back_step, 'forwardStep' => $forward_step)), 'setting'); - drupal_add_css(drupal_get_path('module', 'taxonomy') . '/taxonomy.css'); } drupal_add_tabledrag('taxonomy', 'order', 'sibling', 'term-weight'); diff --git a/core/modules/taxonomy/taxonomy.module b/core/modules/taxonomy/taxonomy.module index a5bdcf7..ce8b274 100644 --- a/core/modules/taxonomy/taxonomy.module +++ b/core/modules/taxonomy/taxonomy.module @@ -1703,3 +1703,27 @@ function taxonomy_entity_query_alter($query) { unset($conditions['bundle']); } } + +/** + * Implements hook_library_info(). + */ +function taxonomy_library_info() { + $libraries['drupal.taxonomy'] = array( + 'title' => 'Taxonomy', + 'version' => VERSION, + 'js' => array( + drupal_get_path('module', 'taxonomy') . '/taxonomy.js' => array(), + ), + 'css' => array( + drupal_get_path('module', 'taxonomy') . '/taxonomy.css' => array(), + ), + 'dependencies' => array( + array('system', 'jquery'), + array('system', 'drupal'), + array('system', 'drupal.settings'), + array('system', 'drupal.tabledrag'), + ), + ); + + return $libraries; +} diff --git a/core/modules/toolbar/toolbar.module b/core/modules/toolbar/toolbar.module index 70f12bf..72d749c 100644 --- a/core/modules/toolbar/toolbar.module +++ b/core/modules/toolbar/toolbar.module @@ -192,17 +192,10 @@ function toolbar_view() { $build = array( '#theme' => 'toolbar', '#attached'=> array( - 'js' => array( - $module_path . '/toolbar.js', - array( - 'data' => array('tableHeaderOffset' => 'Drupal.toolbar.height'), - 'type' => 'setting' - ), + 'library' => array( + array('toolbar', 'drupal.toolbar'), + array('system', 'jquery.cookie'), ), - 'css' => array( - $module_path . '/toolbar.css', - ), - 'library' => array(array('system', 'jquery.cookie')), ), ); @@ -366,3 +359,32 @@ function toolbar_in_active_trail($path) { } return in_array($path, $active_paths); } + +/** + * Implements hook_library_info(). + */ +function toolbar_library_info() { + $libraries['drupal.toolbar'] = array( + 'title' => 'Toolbar', + 'version' => VERSION, + 'js' => array( + drupal_get_path('module', 'toolbar') . '/toolbar.js' => array(), + array( + 'data' => array('tableHeaderOffset' => 'Drupal.toolbar.height'), + 'type' => 'setting', + ), + ), + 'css' => array( + drupal_get_path('module', 'toolbar') . '/toolbar.css', + ), + 'dependencies' => array( + array('system', 'jquery'), + array('system', 'drupal'), + array('system', 'drupal.settings'), + array('system', 'jquery.once'), + array('system', 'jquery.cookie'), + ), + ); + + return $libraries; +} diff --git a/core/modules/translation/translation.module b/core/modules/translation/translation.module index 909117f..cceb134 100644 --- a/core/modules/translation/translation.module +++ b/core/modules/translation/translation.module @@ -116,8 +116,8 @@ function translation_permission() { function translation_form_node_type_form_alter(&$form, &$form_state) { // Hide form element if default language is a constant. // TODO: When form #states allows OR values change this to use form #states. - $form['#attached']['js'] = array( - drupal_get_path('module', 'translation') . '/translation.js', + $form['#attached']['library'] = array( + array('translation', 'drupal.translation'), ); // Add translation option to content type form. $form['language']['node_type_language_translation_enabled'] = array( @@ -540,3 +540,22 @@ function translation_language_switch_links_alter(array &$links, $type, $path) { } } } + +/** + * Implements hook_library_info(). + */ +function translation_library_info() { + $libraries['drupal.translation'] = array( + 'title' => 'Translation', + 'version' => VERSION, + 'js' => array( + drupal_get_path('module', 'translation') . '/translation.js' => array(), + ), + 'dependencies' => array( + array('system', 'jquery'), + array('system', 'drupal'), + ), + ); + + return $libraries; +} diff --git a/core/modules/user/user.admin.inc b/core/modules/user/user.admin.inc index fac9723..6b37de3 100644 --- a/core/modules/user/user.admin.inc +++ b/core/modules/user/user.admin.inc @@ -359,7 +359,7 @@ function user_admin_settings() { '#title' => t('Enable user pictures.'), '#default_value' => $picture_support, ); - drupal_add_js(drupal_get_path('module', 'user') . '/user.js'); + $form['#attached']['library'][] = array('user', 'drupal.user'); $form['personalization']['pictures'] = array( '#type' => 'container', '#states' => array( @@ -721,7 +721,7 @@ function user_admin_permissions($form, $form_state, $rid = NULL) { $form['actions'] = array('#type' => 'actions'); $form['actions']['submit'] = array('#type' => 'submit', '#value' => t('Save permissions')); - $form['#attached']['js'][] = drupal_get_path('module', 'user') . '/user.permissions.js'; + $form['#attached']['library'][] = array('user', 'drupal.user.permissions'); return $form; } diff --git a/core/modules/user/user.module b/core/modules/user/user.module index 535a579..775896e 100644 --- a/core/modules/user/user.module +++ b/core/modules/user/user.module @@ -3063,7 +3063,7 @@ function user_form_process_password_confirm($element) { ), ); - $element['#attached']['js'][] = drupal_get_path('module', 'user') . '/user.js'; + $element['#attached']['library'][] = array('user', 'drupal.user'); // Ensure settings are only added once per page. static $already_added = FALSE; if (!$already_added) { @@ -3180,7 +3180,7 @@ function user_form_field_ui_field_edit_form_alter(&$form, &$form_state, $form_id // a custom behavior, since the #states system would also synchronize on // uncheck. '#attached' => array( - 'js' => array(drupal_get_path('module', 'user') . '/user.js'), + 'library' => array(array('user', 'drupal.user')), ), ); @@ -3296,3 +3296,36 @@ function user_file_download_access($field, $entity_type, $entity) { return user_view_access($entity); } } + +/** + * Implements hook_library_info(). + */ +function user_library_info() { + $libraries['drupal.user'] = array( + 'title' => 'User', + 'version' => VERSION, + 'js' => array( + drupal_get_path('module', 'user') . '/user.js' => array(), + ), + 'dependencies' => array( + array('system', 'jquery'), + array('system', 'drupal'), + array('system', 'jquery.once'), + ), + ); + + $libraries['drupal.user.permissions'] = array( + 'title' => 'User permissions', + 'version' => VERSION, + 'js' => array( + drupal_get_path('module', 'user') . '/user.permissions.js' => array(), + ), + 'dependencies' => array( + array('system', 'jquery'), + array('system', 'drupal'), + array('system', 'drupal.settings'), + ), + ); + + return $libraries; +}