From 31b962545439d50e090656f65ca2d6ce846aebe8 Mon Sep 17 00:00:00 2001
From: mfer <mfer@25701.no-reply.drupal.org>
Date: Mon, 20 Feb 2012 09:17:31 +0800
Subject: [PATCH] Issue #1089300: clean up drupal.js

---
 core/misc/drupal.js |  136 ++++++++++++++++++++++++++++----------------------
 1 files changed, 76 insertions(+), 60 deletions(-)

diff --git a/core/misc/drupal.js b/core/misc/drupal.js
index 83b0884..7826000 100644
--- a/core/misc/drupal.js
+++ b/core/misc/drupal.js
@@ -1,10 +1,9 @@
-
 var Drupal = Drupal || { 'settings': {}, 'behaviors': {}, 'locale': {} };
 
 // Allow other JavaScript libraries to use $.
 jQuery.noConflict();
 
-(function ($) {
+(function ($, Drupal, window, document, undefined) {
 
 /**
  * Attach all registered behaviors to a page element.
@@ -23,17 +22,18 @@ jQuery.noConflict();
  *    };
  * @endcode
  *
- * Drupal.attachBehaviors is added below to the jQuery ready event and so
- * runs on initial page load. Developers implementing AHAH/Ajax in their
- * solutions should also call this function after new page content has been
- * loaded, feeding in an element to be processed, in order to attach all
- * behaviors to the new content.
+ * Drupal.attachBehaviors is added below to the jQuery.ready event and therefore
+ * runs on initial page load. Developers implementing Ajax in their solutions
+ * should also call this function after new page content has been loaded,
+ * feeding in an element to be processed, in order to attach all behaviors to
+ * the new content.
  *
  * Behaviors should use
  * @code
- *   $(selector).once('behavior-name', function () {
+ *   var elements = $(selector).once('behavior-name');
+ *   if (elements.length) {
  *     ...
- *   });
+ *   }
  * @endcode
  * to ensure the behavior is attached only once to a given element. (Doing so
  * enables the reprocessing of given elements, which may be needed on occasion
@@ -43,18 +43,20 @@ jQuery.noConflict();
  *   An element to attach behaviors to. If none is given, the document element
  *   is used.
  * @param settings
- *   An object containing settings for the current context. If none given, the
- *   global Drupal.settings object is used.
+ *   An object containing settings for the current context. If none is given,
+ *   the global Drupal.settings object is used.
  */
 Drupal.attachBehaviors = function (context, settings) {
+  var behaviors = Drupal.behaviors,
+      i;
   context = context || document;
   settings = settings || Drupal.settings;
   // Execute all of them.
-  $.each(Drupal.behaviors, function () {
-    if ($.isFunction(this.attach)) {
-      this.attach(context, settings);
+  for (i in behaviors) {
+    if (behaviors.hasOwnProperty(i) && behaviors[i].attach) {
+      behaviors[i].attach(context, settings);
     }
-  });
+  }
 };
 
 /**
@@ -98,32 +100,31 @@ Drupal.attachBehaviors = function (context, settings) {
  * @see Drupal.attachBehaviors
  */
 Drupal.detachBehaviors = function (context, settings, trigger) {
+  var behaviors = Drupal.behaviors,
+      i;
   context = context || document;
   settings = settings || Drupal.settings;
   trigger = trigger || 'unload';
   // Execute all of them.
-  $.each(Drupal.behaviors, function () {
-    if ($.isFunction(this.detach)) {
-      this.detach(context, settings, trigger);
+  for (i in behaviors) {
+    if (behaviors.hasOwnProperty(i) && behaviors[i].detach) {
+      behaviors[i].detach(context, settings, trigger);
     }
-  });
+  }
 };
 
 /**
  * Encode special characters in a plain-text string for display as HTML.
  *
+ * @param str
+ *   The string to be encoded.
+ * @return
+ *   The encoded string.
  * @ingroup sanitization
  */
 Drupal.checkPlain = function (str) {
-  var character, regex,
-      replace = { '&': '&amp;', '"': '&quot;', '<': '&lt;', '>': '&gt;' };
-  str = String(str);
-  for (character in replace) {
-    if (replace.hasOwnProperty(character)) {
-      regex = new RegExp(character, 'g');
-      str = str.replace(regex, replace[character]);
-    }
-  }
+  str = str.toString();
+  str = str.replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
   return str;
 };
 
@@ -235,10 +236,10 @@ Drupal.formatPlural = function (count, singular, plural, args, options) {
   // Determine the index of the plural form.
   var index = Drupal.locale.pluralFormula ? Drupal.locale.pluralFormula(args['@count']) : ((args['@count'] == 1) ? 0 : 1);
 
-  if (index == 0) {
+  if (index === 0) {
     return Drupal.t(singular, args, options);
   }
-  else if (index == 1) {
+  else if (index === 1) {
     return Drupal.t(plural, args, options);
   }
   else {
@@ -302,25 +303,29 @@ Drupal.unfreezeHeight = function () {
  * For aesthetic reasons slashes are not escaped.
  */
 Drupal.encodePath = function (item, uri) {
-  uri = uri || location.href;
-  return encodeURIComponent(item).replace(/%2F/g, '/');
+  uri = uri || window.location.href;
+  return window.encodeURIComponent(item).replace(/%2F/g, '/');
 };
 
 /**
  * Get the text selection in a textarea.
  */
 Drupal.getSelection = function (element) {
+  var range1,
+      range2,
+      start,
+      end;
   if (typeof element.selectionStart != 'number' && document.selection) {
     // The current selection.
-    var range1 = document.selection.createRange();
-    var range2 = range1.duplicate();
+    range1 = document.selection.createRange();
+    range2 = range1.duplicate();
     // Select all text.
     range2.moveToElementText(element);
     // Now move 'dummy' end point to end point of original range.
     range2.setEndPoint('EndToEnd', range1);
     // Now we can calculate start and end points.
-    var start = range2.text.length - range1.text.length;
-    var end = start + range1.text.length;
+    start = range2.text.length - range1.text.length;
+    end = start + range1.text.length;
     return { 'start': start, 'end': end };
   }
   return { 'start': element.selectionStart, 'end': element.selectionEnd };
@@ -359,37 +364,34 @@ Drupal.ajaxError = function (xmlhttp, uri) {
   responseText = responseText.replace(/<("[^"]*"|'[^']*'|[^'">])*>/gi,"");
   responseText = responseText.replace(/[\n]+\s+/g,"\n");
 
-  // We don't need readyState except for status == 0.
-  readyStateText = xmlhttp.status == 0 ? ("\n" + Drupal.t("ReadyState: !readyState", {'!readyState': xmlhttp.readyState})) : "";
+  // We don't need readyState except for status === 0.
+  readyStateText = xmlhttp.status === 0 ? ("\n" + Drupal.t("ReadyState: !readyState", {'!readyState': xmlhttp.readyState})) : "";
 
   message = statusCode + pathText + statusText + responseText + readyStateText;
   return message;
 };
 
-// Class indicating that JS is enabled; used for styling purpose.
-$('html').addClass('js');
-
-// 'js enabled' cookie.
-document.cookie = 'has_js=1; path=/';
-
 /**
- * Additions to jQuery.support.
+ * Add properties to the jQuery.support object.
  */
-$(function () {
-  /**
-   * Boolean indicating whether or not position:fixed is supported.
-   */
-  if (jQuery.support.positionFixed === undefined) {
-    var el = $('<div style="position:fixed; top:10px" />').appendTo(document.body);
-    jQuery.support.positionFixed = el[0].offsetTop === 10;
-    el.remove();
-  }
-});
+var enhancejQuerySupport = function () {
+ var el,
+     body = document.body || document.getElementsByTagName("body")[0] || document.documentElement;
+ // Boolean indicating whether or not "position: fixed" is supported.
+ if ($.support.positionFixed === undefined) {
 
-//Attach all behaviors.
-$(function () {
-  Drupal.attachBehaviors(document, Drupal.settings);
-});
+   // Using the DOM to create an element is much faster than using jQuery.
+   el = document.createElement("div");
+   el.style.position = "fixed";
+   el.style.top = "10px";
+
+   // Use insertBefore instead of appendChild to circumvent an IE6 bug.
+   // This arises when a base node is used.
+   body.insertBefore(el, body.firstChild);
+   $.support.positionFixed = el.offsetTop === 10;
+   body.removeChild(el);
+ }
+};
 
 /**
  * The default themes.
@@ -409,4 +411,18 @@ Drupal.theme.prototype = {
   }
 };
 
-})(jQuery);
+// Test for positionFixed before the DOM is ready.
+enhancejQuerySupport();
+
+// Class indicating that JS is enabled; used for styling purposes.
+$('html').addClass('js');
+
+// 'js enabled' cookie.
+document.cookie = 'has_js=1; path=/';
+
+// When the DOM is ready, attach behaviors to the page.
+$(document).ready(function () {
+  Drupal.attachBehaviors(document, Drupal.settings);
+});
+
+})(jQuery, Drupal, this, this.document);
-- 
1.7.8.3

