Index: modules/menu/menu.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/menu/menu.admin.inc,v
retrieving revision 1.54
diff -u -p -r1.54 menu.admin.inc
--- modules/menu/menu.admin.inc	22 Aug 2009 14:34:20 -0000	1.54
+++ modules/menu/menu.admin.inc	22 Aug 2009 16:39:13 -0000
@@ -402,43 +402,54 @@ function menu_edit_item_submit($form, &$
  */
 function menu_edit_menu(&$form_state, $type, $menu = array()) {
   $system_menus = menu_list_system_menus();
-  if ($type == 'edit') {
-    $form['menu_name'] = array('#type' => 'value', '#value' => $menu['menu_name']);
-    $form['#insert'] = FALSE;
-    $form['delete'] = array(
-      '#type' => 'submit',
-      '#value' => t('Delete'),
-      '#access' => !isset($system_menus[$menu['menu_name']]),
-      '#submit' => array('menu_custom_delete_submit'),
-      '#weight' => 10,
-    );
+  $menu += array('menu_name' => '', 'title' => '', 'description' => '');
+
+  $form['#title'] = $menu['title'];
+
+  // The title of a system menu cannot be altered.
+  if (isset($system_menus[$menu['menu_name']])) {
+    $form['title'] = array('#type' => 'value', '#value' => $menu['title']);
   }
   else {
-    $menu = array('menu_name' => '', 'title' => '', 'description' => '');
-    $form['menu_name'] = array(
+    $form['title'] = array(
       '#type' => 'textfield',
-      '#title' => t('Menu name'),
-      '#maxsize' => MENU_MAX_MENU_NAME_LENGTH_UI,
-      '#description' => t('The machine-readable name of this menu. This text will be used for constructing the URL of the <em>menu overview</em> page for this menu. This name must contain only lowercase letters, numbers, and hyphens, and must be unique.'),
+      '#title' => t('Title'),
+      '#default_value' => $menu['title'],
       '#required' => TRUE,
+      '#field_suffix' => ' <small id="edit-title-suffix">&nbsp;</small>',
     );
-    $form['#insert'] = TRUE;
   }
-  $form['#title'] = $menu['title'];
-  if (isset($system_menus[$menu['menu_name']])) {
-    $form['title'] = array(
-      '#type' => 'value',
-      '#value' => $menu['title'],
-    );
+
+  // The internal menu name can only be defined during initial menu creation.
+  if ($type == 'edit') {
+    $form['#insert'] = FALSE;
+    $form['menu_name'] = array('#type' => 'value', '#value' => $menu['menu_name']);
   }
   else {
-    $form['title'] = array(
+    $form['#insert'] = TRUE;
+    $js_settings = array(
+      'type' => 'setting',
+      'data' => array(
+        'machineReadableValue' => array(
+          'title' => array(
+            'text' => t('URL path'),
+            'target' => 'menu-name',
+            'searchPattern' => '[^a-z0-9]+',
+            'replaceToken' => '-',
+          ),
+        ),
+      ),
+    );
+    $form['menu_name'] = array(
       '#type' => 'textfield',
-      '#title' => t('Title'),
-      '#default_value' => $menu['title'],
+      '#title' => t('Menu name'),
+      '#maxsize' => MENU_MAX_MENU_NAME_LENGTH_UI,
+      '#description' => t('This text will be used to construct the URL for the menu. The name must contain only lowercase letters, numbers and hyphens, and must be unique.'),
       '#required' => TRUE,
+      '#attached_js' => array(drupal_get_path('module', 'system') . '/system.js', $js_settings),
     );
   }
+
   $form['description'] = array(
     '#type' => 'textarea',
     '#title' => t('Description'),
@@ -448,6 +459,13 @@ function menu_edit_menu(&$form_state, $t
     '#type' => 'submit',
     '#value' => t('Save'),
   );
+  // Only custom menus may be deleted.
+  $form['delete'] = array(
+    '#type' => 'submit',
+    '#value' => t('Delete'),
+    '#access' => $type == 'edit' && !isset($system_menus[$menu['menu_name']]),
+    '#submit' => array('menu_custom_delete_submit'),
+  );
 
   return $form;
 }
Index: modules/node/content_types.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/node/content_types.inc,v
retrieving revision 1.89
diff -u -p -r1.89 content_types.inc
--- modules/node/content_types.inc	22 Aug 2009 14:34:20 -0000	1.89
+++ modules/node/content_types.inc	22 Aug 2009 16:39:13 -0000
@@ -58,7 +58,6 @@ function theme_node_admin_overview($name
  * Generates the node type editing form.
  */
 function node_type_form(&$form_state, $type = NULL) {
-  drupal_add_js(drupal_get_path('module', 'node') . '/content_types.js');
   if (!isset($type->type)) {
     // This is a new type. Node module managed types are custom and unlocked.
     $type = node_type_set_defaults(array('custom' => 1, 'locked' => 0));
@@ -78,10 +77,23 @@ function node_type_form(&$form_state, $t
     '#description' => t('The human-readable name of this content type. This text will be displayed as part of the list on the <em>add new content</em> page. It is recommended that this name begin with a capital letter and contain only letters, numbers, and <strong>spaces</strong>. This name must be unique.'),
     '#required' => TRUE,
     '#size' => 30,
-    '#field_suffix' => ' <small id="node-type-name-suffix">&nbsp;</small>',
+    '#field_suffix' => ' <small id="edit-name-suffix">' . ($type->locked ? t('Machine name: @name', array('@name' => $type->type)) : '&nbsp') . '</small>',
   );
 
   if (!$type->locked) {
+    $js_settings = array(
+      'type' => 'setting',
+      'data' => array(
+        'machineReadableValue' => array(
+          'name' => array(
+            'text' => t('Machine name'),
+            'target' => 'type',
+            'searchPattern' => '[^a-z0-9]+',
+            'replaceToken' => '_',
+          ),
+        ),
+      ),
+    );
     $form['identity']['type'] = array(
       '#title' => t('Machine name'),
       '#type' => 'textfield',
@@ -89,6 +101,7 @@ function node_type_form(&$form_state, $t
       '#maxlength' => 32,
       '#required' => TRUE,
       '#description' => t('The machine-readable name of this content type. This text will be used for constructing the URL of the <em>add new content</em> page for this content type. This name must contain only lowercase letters, numbers, and underscores. Underscores will be converted into hyphens when constructing the URL of the <em>add new content</em> page. This name must be unique.'),
+      '#attached_js' => array(drupal_get_path('module', 'system') . '/system.js', $js_settings),
     );
   }
   else {
@@ -96,12 +109,6 @@ function node_type_form(&$form_state, $t
       '#type' => 'value',
       '#value' => $type->type,
     );
-    $form['identity']['type_display'] = array(
-      '#title' => t('Machine name'),
-      '#type' => 'item',
-      '#markup' => theme('placeholder', $type->type),
-      '#description' => t('The machine-readable name of this content type. This field cannot be modified for system-defined content types.'),
-    );
   }
 
   $form['identity']['description'] = array(
Index: modules/node/content_types.js
===================================================================
RCS file: /cvs/drupal/drupal/modules/node/content_types.js,v
retrieving revision 1.6
diff -u -p -r1.6 content_types.js
--- modules/node/content_types.js	21 Aug 2009 00:21:48 -0000	1.6
+++ modules/node/content_types.js	22 Aug 2009 16:39:13 -0000
@@ -30,28 +30,6 @@ Drupal.behaviors.contentTypes = {
       }
       return vals.join(', ');
     });
-
-    // Process the machine name.
-    if ($('#edit-type').val() == $('#edit-name').val().toLowerCase().replace(/[^a-z0-9]+/g, '_').replace(/_+/g, '_') || $('#edit-type').val() == '') {
-      $('.form-item.type-wrapper').hide();
-      $('#edit-name').keyup(function () {
-        var machine = $(this).val().toLowerCase().replace(/[^a-z0-9]+/g, '_').replace(/_+/g, '_');
-        if (machine != '_' && machine != '') {
-          $('#edit-type').val(machine);
-          $('#node-type-name-suffix').empty().append(' Machine name: ' + machine + ' [').append($('<a href="#">' + Drupal.t('Edit') + '</a>').click(function () {
-            $('.form-item-textfield.type-wrapper').show();
-            $('#node-type-name-suffix').hide();
-            $('#edit-name').unbind('keyup');
-            return false;
-          })).append(']');
-        }
-        else {
-          $('#edit-type').val(machine);
-          $('#node-type-name-suffix').text('');
-        }
-      });
-      $('#edit-name').keyup();
-    }
   }
 };
 
Index: modules/system/system.js
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.js,v
retrieving revision 1.30
diff -u -p -r1.30 system.js
--- modules/system/system.js	12 Aug 2009 11:43:10 -0000	1.30
+++ modules/system/system.js	22 Aug 2009 16:39:14 -0000
@@ -169,5 +169,67 @@ Drupal.behaviors.pageCache = {
   },
 };
 
+/**
+ * Attach the auto machine readable name behavior.
+ *
+ * Settings are expected to be an object of elements to process, where the key
+ * defines the source element in the form and the value is an object defining
+ * the following properties:
+ * - text: The label to display before the auto-generated value.
+ * - target: The target form element name.
+ * - searchPattern: A regular expression (without modifiers) matching disallowed
+ *   characters in the machine readable name, f.e. '[^a-z0-9]+'.
+ * - replaceToken: A replacement string to replace disallowed characters, f.e.
+ *   '-' or '_'.
+ *
+ * @see menu_edit_menu()
+ */
+Drupal.behaviors.machineReadableValue = {
+  attach: function () {
+    for (var value in Drupal.settings.machineReadableValue) {
+      var settings = Drupal.settings.machineReadableValue[value];
+
+      var searchPattern = new RegExp(settings.searchPattern, 'g');
+      // Build selector for the source name entered by a user.
+      var source = '#edit-' + value;
+      var suffix = source + '-suffix';
+      // Build selector for the machine readable name.
+      var target = '#edit-' + settings.target;
+      // Build selector for the wrapper element around the target field.
+      var wrapper = '.' + settings.target + '-wrapper';
+
+      // Do not process the element if we got an error or the given name and the
+      // machine readable name are identical or the machine readable name is
+      // empty.
+      if (!$(target).hasClass('error') && ($(target).val() == $(source).val().toLowerCase().replace(searchPattern, settings.replaceToken) || $(target).val() == '')) {
+        // Hide wrapper element.
+        $(wrapper).hide();
+        // Bind keyup event to source element.
+        $(source).keyup(function () {
+          var machine = $(this).val().toLowerCase().replace(searchPattern, settings.replaceToken);
+          if (machine != '_' && machine != '') {
+            // Set machine readable name to the user entered value.
+            $(target).val(machine);
+            // Append the machine readable name and a link to edit it to the source field.
+            $(suffix).empty().append(' ' + settings.text + ': ' + machine + ' [').append($('<a href="#">' + Drupal.t('Edit') + '</a>').click(function () {
+              $(wrapper).show();
+              $(target).focus();
+              $(suffix).hide();
+              $(source).unbind('keyup');
+              return false;
+            })).append(']');
+          }
+          else {
+            $(target).val(machine);
+            $(suffix).text('');
+          }
+        });
+        // Call keyup event on source element.
+        $(source).keyup();
+      }
+    }
+  }
+};
+
 })(jQuery);
 
