From 5109e619cc4b640492fa9c2acf6e44b082383502 Mon Sep 17 00:00:00 2001 From: Alexis Wilke Date: Sat, 15 May 2010 10:47:59 +0000 Subject: [PATCH] Changes to support a fixed position (i.e. does not scroll with the page.) Put the menu inside a
block (so fixed position works.) Added support to switch between versions of superfish. Added support for z-index parameter in admin screen. --- simplemenu.admin.inc | 80 ++++++++++++++++++++++----- simplemenu.module | 128 ++++++++++++++++++++++++++++++++++++++----- 2 files changed, 181 insertions(+), 27 deletions(-) diff --git a/simplemenu.admin.inc b/simplemenu.admin.inc index 5977d58d..0e47f6a5 100644 --- a/simplemenu.admin.inc +++ b/simplemenu.admin.inc @@ -58,6 +58,19 @@ function simplemenu_admin_settings() { '#collapsed' => TRUE, ); + $fix_options = array( + 'scroll' => t('Scroll with page'), + 'top' => t('Fix at the Top (Forces Body, Prepend)'), + //'bottom' => t('Fix at the Bottom (Forces Body, Append)'), -- this requires another CSS... hmmm... + ); + $form['settings']['simplemenu_fix'] = array( + '#type' => 'radios', + '#title' => t('Scroll or fix menu'), + '#options' => $fix_options, + '#default_value' => variable_get('simplemenu_fix', 'scroll'), + '#description' => t('Select the mode to use. The default is to let the menu scroll with the page.
WARNING: The At the Top/Bottom options prevent you from ever seeing the bottom of your drop-down menus. In other words, if you have many modules installed, it is not unlikely that your Site configuration menu will not fit the screen and the last few entries won\'t be accessible via Simplemenu.'), + ); + $form['settings']['simplemenu_hide_delay'] = array( '#type' => 'textfield', '#title' => t('Hide delay'), @@ -66,17 +79,6 @@ function simplemenu_admin_settings() { '#description' => t('How long (in milliseconds) should a menu still appear after losing focus.'), ); - $form['settings']['simplemenu_scroll_effect'] = array( - '#type' => 'radios', - '#title' => t('Scroll effect'), - '#options' => array( - 'scroll' => t('Scroll with the page'), - 'fixed' => t('Fixed'), - ), - '#default_value' => variable_get('simplemenu_scroll_effect', 'scroll'), - '#description' => t('Whether the menu scrolls with the page or stays at the top or bottom (this should only be used when the menu is attached to the <body> tag.)'), - ); - $form['settings']['simplemenu_effect'] = array( '#type' => 'radios', '#title' => t('Show effect'), @@ -113,6 +115,34 @@ function simplemenu_admin_settings() { '#default_value' => variable_get('simplemenu_uid1', 1), ); + $simplemenu_path = drupal_get_path('module', 'simplemenu'); + $superfish = file_scan_directory($simplemenu_path, '^superfish-[0-9.]*\.js$', + array('.', '..', 'CVS', '.svn'), 0, FALSE, 'basename'); + foreach ($superfish as $name => $ignore) { + $superfish[$name] = $name; + } + $form['advanced']['simplemenu_superfish_version'] = array( + '#type' => 'select', + '#title' => t('SuperFish Version'), + '#options' => $superfish, + '#description' => t('Select which version of SuperFish you prefer using.') .$simplemenu_path, + '#default_value' => variable_get('simplemenu_superfish_version', 'superfish-1.4.1.js'), + ); + + $form['advanced']['simplemenu_menubar_zindex'] = array( + '#type' => 'textfield', + '#title' => t('Menubar CSS z-index value'), + '#description' => t('By default, the menubar CSS z-index is set to 1. Some themes or other modules may require you to change this value. Use -1 to completely disable the z-index in the menubar.'), + '#default_value' => variable_get('simplemenu_menubar_zindex', 9999), + ); + + $form['advanced']['simplemenu_dropdown_zindex'] = array( + '#type' => 'textfield', + '#title' => t('Dropdown CSS z-index value'), + '#description' => t('By default, the dropdown CSS z-index is set to 9999. However, some themes and modules use an even larger z-index. For instance, the AddThis overlay is put at z-index 100,000 (although from my tests, it seems that they use a much higher z-index...). So if you want the Simplemenu to appear over the AddThis pop-up, you want to use a z-index which is even larger (i.e. 2,000,000 [do not enter the commas!].) On the other hand, 9999 may be too large for your site. You can use a smaller number if that works better for you. Use -1 to not remove the z-index from your dropdown.'), + '#default_value' => variable_get('simplemenu_dropdown_zindex', 9999), + ); + $form['advanced']['simplemenu_element'] = array( '#type' => 'textfield', '#title' => t('CSS selector to attach menu to'), @@ -127,9 +157,10 @@ function simplemenu_admin_settings() { '#options' => array( 'prepend' => t('Prepend'), 'append' => t('Append'), + 'replace' => t('Replace'), ), '#default_value' => variable_get('simplemenu_element_method', 'prepend'), - '#description' => t('Choose how the menu should be attached to the above selector.'), + '#description' => t('Choose how the menu should be attached to the above selector.
WARNING: The Replace option should only be used with a specialized theme that offers a tag that is to be replaced by the simple menu. Make sure you don\'t use that option with your body!'), '#required' => TRUE, ); @@ -145,10 +176,10 @@ function simplemenu_admin_settings() { '#description' => t('Select which themes to not display the menu. Use this when you have a theme that displays its own admin navigation.'), ); - $form['advanced']['simplemenu_detect_popop'] = array( + $form['advanced']['simplemenu_detect_popup'] = array( '#type' => 'checkbox', '#title' => t('Detect pop-up windows'), - '#default_value' => variable_get('simplemenu_detect_popop', 1), + '#default_value' => variable_get('simplemenu_detect_popup', 1), '#description' => t("Choose whether SimpleMenu should attempt to detect if it is inside of a pop-up window. If enabled, SimpleMenu will not display if it is inside of a pop-up window."), ); @@ -171,7 +202,28 @@ function simplemenu_admin_settings() { '#wysiwyg' => FALSE, ); + $form['#validate'][] = 'simplemenu_admin_settings_validate'; + $form['#submit'][] = 'simplemenu_admin_settings_submit'; + return system_settings_form($form); } +/** + * Verify that we have settings that are sensical. + */ +function simplemenu_admin_settings_validate($form, &$form_state) { + $values = &$form_state['values']; + if ($values['simplemenu_fix'] != 'scroll' && $values['simplemenu_menubar_zindex'] < 1) { + form_set_error('simplemenu_menubar_zindex', t('In order to use a Fix mode, you want to increase the menubar z-index value to 1 or more.')); + } +} +/** + * Handle some special cases. + */ +function simplemenu_admin_settings_submit($form, $form_state) { + // make sure we regenerate the CSS file + variable_set('simplemenu_css_filename', ''); +} + +// vim: ts=2 sw=2 et syntax=php diff --git a/simplemenu.module b/simplemenu.module index 19805461..d40bdc52 100644 --- a/simplemenu.module +++ b/simplemenu.module @@ -48,30 +48,131 @@ function simplemenu_enabled() { function simplemenu_init() { // do a simple access check here, since theme isn't available to check yet if (user_access('view simplemenu') && simplemenu_enabled()) { - $path = drupal_get_path('module', 'simplemenu'); - drupal_add_css($path .'/simplemenu.css'); + $simplemenu_path = drupal_get_path('module', 'simplemenu'); + $css_path = file_create_path('css'); // same path as concatenated Core CSS + if (file_check_directory($css_path, FILE_CREATE_DIRECTORY)) { + // The old way had a "static" CSS which meant that we could not easily + // offer options to the users. + //drupal_add_css($simplemenu_path .'/simplemenu.css'); + $fix = variable_get('simplemenu_fix', 'scroll'); + + // XXX add a variable simplemenu_update which is set to TRUE whenever + // the settings get modified and false here + $output_filename = variable_get('simplemenu_css_filename', ''); + if (!$output_filename) { + $tags = array( + '@MENUBAR_ZINDEX@' => simplemnu_get_zindex('simplemenu_menubar_zindex', 9999), + '@DROPDOWN_ZINDEX@' => simplemnu_get_zindex('simplemenu_dropdown_zindex', 9999), + ); + switch ($fix) { + case 'top': + $tags['@FIX@'] = "position: fixed;\n top: 0;"; + break; + + case 'bottom': + $tags['@FIX@'] = "position: fixed;\n bottom: 0;"; + break; + + default: // scroll + $tags['@FIX@'] = 'position: relative;'; + break; + + } + $css = file_get_contents($simplemenu_path . '/simplemenu.css.tpl'); + $css = strtr($css, $tags); + $css_md5 = md5($css); + $output_filename = $css_path . '/simplemenu-' . $css_md5 . '.css'; + if (!file_exists($output_filename)) { + // new content, create a new file + file_put_contents($output_filename, $css); + } + else { + // this call is rather ugly, but we must make sure that the + // system cache will take the current Simplemenu CSS in account + _drupal_flush_css_js(); + } + //variable_set('simplemenu_css_filename', $output_filename); + } + drupal_add_css($output_filename); + } + else { + drupal_set_message(t('Simplemenu could not create the folder @path in order to save the dynamic CSS data.', + array('@path' => $css_path)), 'error'); + + // use a default that cannot react to the dynamic changes... + drupal_add_css($simplemenu_path .'/simplemenu.css'); + } + + // we want to put the simplemenu theme CSS first + // so we can change some CSS entries dynamically + // but at this time the simplemenu.css is used to + // reset many of the CSS entries... Hmmm... $simplemenu_theme = variable_get('simplemenu_theme', 'original'); - $theme_file = $path .'/themes/'. $simplemenu_theme .'/'. $simplemenu_theme .'.css'; + $theme_file = $simplemenu_path .'/themes/'. $simplemenu_theme .'/'. $simplemenu_theme .'.css'; if (is_file($theme_file)) { drupal_add_css($theme_file); } + switch ($fix) { + case 'top': + $element = 'body'; + $placement = 'prepend'; + break; + + case 'bottom': + $element = 'body'; + $placement = 'append'; + break; + + default: // 'scroll' + // let user defined other elements when not fixed + $element = variable_get('simplemenu_element', 'body'); + $placement = variable_get('simplemenu_element_method', 'prepend'); + break; + + } + $settings = array( 'effect' => variable_get('simplemenu_effect', 'opacity'), 'effectSpeed' => variable_get('simplemenu_effect_speed', 'fast'), - 'element' => variable_get('simplemenu_element', 'body'), + 'element' => $element, + 'placement' => $placement, 'hideDelay' => variable_get('simplemenu_hide_delay', 800), - 'placement' => variable_get('simplemenu_element_method', 'prepend'), - 'detectPopup' => variable_get('simplemenu_detect_popop', 1), + 'detectPopup' => variable_get('simplemenu_detect_popup', 1), ); drupal_add_js(array('simplemenu' => $settings), 'setting'); - drupal_add_js($path .'/simplemenu.js'); - drupal_add_js($path .'/superfish.js'); + drupal_add_js($simplemenu_path . '/simplemenu.js'); + $superfish = variable_get('simplemenu_superfish_version', 'superfish-1.4.1.js'); + drupal_add_js($simplemenu_path . '/' . $superfish); } } +/** + * \brief Retrieve the zindex for the CSS files. + * + * This function retrieves a z-index from a Drupal variable and + * transform it to fit in a CSS file. + * + * \param[in] $name The name of the z-index variable to read. + * \param[in] $default The default value to use when the variable is not defined. + * + * \return A string representing the current value of the specified z-index. + */ +function simplemnu_get_zindex($name, $default) { + $zindex = variable_get($name, $default); + + if ($zindex == -1) { + $zindex = ''; + } + else { + $zindex = 'z-index: ' . $zindex . ';'; + } + + return $zindex; +} + /** * Implementation of hook_footer(). * @@ -104,15 +205,13 @@ function simplemenu_perm() { * Render an HTML list of links for a given menu. */ function simplemenu_get_menu() { - $output = ''; - // if a user turned off menu module but SimpleMenu was previously set // reset variable so a menu appears $menu_name = module_exists('menu') ? variable_get('simplemenu_menu', 'navigation:0') : 'navigation:0'; $menu = simplemenu_menu_tree($menu_name); if (!$menu) { - $menu = '
  • '. t('No menu items found. Try a different menu as the default.') .'
  • '; + $menu = ''; } // This is ugly, I know, but it is the only way I can see to get the additional @@ -122,9 +221,12 @@ function simplemenu_get_menu() { $menu = substr($menu, 0, $pos) . $devel . substr($menu, $pos); } - $output .= $menu; + // add the class & id to the UL tag here instead of the JavaScript + // otherwise it could be added to the
    tag instead... + $pos = strpos($menu, '>') + 1; + $menu = '