summaryrefslogtreecommitdiff
path: root/misc/drupal.js
diff options
context:
space:
mode:
Diffstat (limited to 'misc/drupal.js')
-rw-r--r--misc/drupal.js351
1 files changed, 84 insertions, 267 deletions
diff --git a/misc/drupal.js b/misc/drupal.js
index 927403ab1..fb0cf0ddf 100644
--- a/misc/drupal.js
+++ b/misc/drupal.js
@@ -1,39 +1,14 @@
// $Id$
-/**
- * Only enable Javascript functionality if all required features are supported.
- */
-function isJsEnabled() {
- if (typeof document.jsEnabled == 'undefined') {
- // Note: ! casts to boolean implicitly.
- document.jsEnabled = !(
- !document.getElementsByTagName ||
- !document.createElement ||
- !document.createTextNode ||
- !document.documentElement ||
- !document.getElementById);
- }
- return document.jsEnabled;
-}
-
-// Global Killswitch on the <html> element
-if (isJsEnabled()) {
- document.documentElement.className = 'js';
-}
+var Drupal = Drupal || {};
/**
- * The global Drupal variable.
+ * Set the variable that indicates if JavaScript behaviors should be applied
*/
-Drupal = { };
+Drupal.jsEnabled = document.getElementsByTagName && document.createElement && document.createTextNode && document.documentElement && document.getElementById;
/**
- * Merge an object into the Drupal namespace.
- *
- * @param obj
- * The object that should be merged into the Drupal namespace. Arbitrary objects
- * containing functions, variables or other objects can be used. An example object
- * would be { settings: { tree: { '/js/menu/tree': { mid: 206 } } } }. This item
- * can now be accessed at Drupal.settings.tree['/js/menu/tree'].mid.
+ * Extends the current object with the parameter. Works recursively.
*/
Drupal.extend = function(obj) {
for (var i in obj) {
@@ -44,109 +19,26 @@ Drupal.extend = function(obj) {
this[i] = obj[i];
}
}
-};
-
-/**
- * Make IE's XMLHTTP object accessible through XMLHttpRequest()
- */
-if (typeof XMLHttpRequest == 'undefined') {
- XMLHttpRequest = function () {
- var msxmls = ['MSXML3', 'MSXML2', 'Microsoft']
- for (var i=0; i < msxmls.length; i++) {
- try {
- return new ActiveXObject(msxmls[i]+'.XMLHTTP')
- }
- catch (e) { }
- }
- throw new Error("No XML component installed!");
- }
-}
-
-/**
- * Creates an HTTP GET request and sends the response to the callback function.
- *
- * Note that dynamic arguments in the URI should be escaped with encodeURIComponent().
- */
-function HTTPGet(uri, callbackFunction, callbackParameter) {
- var xmlHttp = new XMLHttpRequest();
- var bAsync = true;
- if (!callbackFunction) {
- bAsync = false;
- }
-
- xmlHttp.open('GET', uri, bAsync);
- xmlHttp.send(null);
-
- if (bAsync) {
- xmlHttp.onreadystatechange = function() {
- if (xmlHttp.readyState == 4) {
- callbackFunction(xmlHttp.responseText, xmlHttp, callbackParameter);
- }
- }
- return xmlHttp;
- }
- else {
- return xmlHttp.responseText;
- }
-}
-
-/**
- * Creates an HTTP POST request and sends the response to the callback function
- *
- * Note: passing null or undefined for 'object' makes the request fail in Opera 8.
- * Pass an empty string instead.
- */
-function HTTPPost(uri, callbackFunction, callbackParameter, object) {
- var xmlHttp = new XMLHttpRequest();
- var bAsync = true;
- if (!callbackFunction) {
- bAsync = false;
- }
- xmlHttp.open('POST', uri, bAsync);
-
- var toSend = '';
- if (typeof object == 'object') {
- xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
- for (var i in object) {
- toSend += (toSend ? '&' : '') + i + '=' + encodeURIComponent(object[i]);
- }
- }
- else {
- toSend = object;
- }
- xmlHttp.send(toSend);
-
- if (bAsync) {
- xmlHttp.onreadystatechange = function() {
- if (xmlHttp.readyState == 4) {
- callbackFunction(xmlHttp.responseText, xmlHttp, callbackParameter);
- }
- }
- return xmlHttp;
- }
- else {
- return xmlHttp.responseText;
- }
-}
+},
/**
* Redirects a button's form submission to a hidden iframe and displays the result
* in a given wrapper. The iframe should contain a call to
* window.parent.iframeHandler() after submission.
*/
-function redirectFormButton(uri, button, handler) {
- // (Re)create an iframe to target.
- createIframe();
-
+Drupal.redirectFormButton = function (uri, button, handler) {
// Trap the button
button.onmouseover = button.onfocus = function() {
button.onclick = function() {
+ // Create target iframe
+ Drupal.createIframe();
+
// Prepare variables for use in anonymous function.
var button = this;
var action = button.form.action;
var target = button.form.target;
- // Redirect form submission
+ // Redirect form submission to iframe
this.form.action = uri;
this.form.target = 'redirect-target';
@@ -154,7 +46,7 @@ function redirectFormButton(uri, button, handler) {
// Set iframe handler for later
window.iframeHandler = function () {
- var iframe = $('redirect-target');
+ var iframe = $('#redirect-target').get(0);
// Restore form submission
button.form.action = action;
button.form.target = target;
@@ -173,16 +65,15 @@ function redirectFormButton(uri, button, handler) {
response = null;
}
- $('redirect-target').onload = null;
- $('redirect-target').src = 'about:blank';
-
- response = parseJson(response);
+ response = Drupal.parseJson(response);
// Check response code
if (response.status == 0) {
handler.onerror(response.data);
return;
}
handler.oncomplete(response.data);
+
+ return true;
}
return true;
@@ -191,43 +82,12 @@ function redirectFormButton(uri, button, handler) {
button.onmouseout = button.onblur = function() {
button.onclick = null;
}
-}
-
-/**
- * Adds a function to the window onload event
- */
-function addLoadEvent(func) {
- var oldOnload = window.onload;
- if (typeof window.onload != 'function') {
- window.onload = func;
- }
- else {
- window.onload = function() {
- oldOnload();
- func();
- }
- }
-}
-
-/**
- * Adds a function to a given form's submit event
- */
-function addSubmitEvent(form, func) {
- var oldSubmit = form.onsubmit;
- if (typeof oldSubmit != 'function') {
- form.onsubmit = func;
- }
- else {
- form.onsubmit = function() {
- return oldSubmit() && func();
- }
- }
-}
+},
/**
* Retrieves the absolute position of an element on the screen
*/
-function absolutePosition(el) {
+Drupal.absolutePosition = function (el) {
var sLeft = 0, sTop = 0;
var isDiv = /^div$/i.test(el.tagName);
if (isDiv && el.scrollLeft) {
@@ -238,152 +98,109 @@ function absolutePosition(el) {
}
var r = { x: el.offsetLeft - sLeft, y: el.offsetTop - sTop };
if (el.offsetParent) {
- var tmp = absolutePosition(el.offsetParent);
+ var tmp = Drupal.absolutePosition(el.offsetParent);
r.x += tmp.x;
r.y += tmp.y;
}
return r;
-};
-
-function dimensions(el) {
- return { width: el.offsetWidth, height: el.offsetHeight };
-}
+},
/**
- * Returns true if an element has a specified class name
+ * Return the dimensions of an element on the screen
*/
-function hasClass(node, className) {
- if (node.className == className) {
- return true;
- }
- var reg = new RegExp('(^| )'+ className +'($| )')
- if (reg.test(node.className)) {
- return true;
- }
- return false;
-}
-
-/**
- * Adds a class name to an element
- */
-function addClass(node, className) {
- if (hasClass(node, className)) {
- return false;
- }
- node.className += ' '+ className;
- return true;
-}
-
-/**
- * Removes a class name from an element
- */
-function removeClass(node, className) {
- if (!hasClass(node, className)) {
- return false;
- }
- // Replaces words surrounded with whitespace or at a string border with a space. Prevents multiple class names from being glued together.
- node.className = eregReplace('(^|\\s+)'+ className +'($|\\s+)', ' ', node.className);
- return true;
-}
-
-/**
- * Toggles a class name on or off for an element
- */
-function toggleClass(node, className) {
- if (!removeClass(node, className) && !addClass(node, className)) {
- return false;
- }
- return true;
-}
-
-/**
- * Emulate PHP's ereg_replace function in javascript
- */
-function eregReplace(search, replace, subject) {
- return subject.replace(new RegExp(search,'g'), replace);
-}
-
-/**
- * Removes an element from the page
- */
-function removeNode(node) {
- if (typeof node == 'string') {
- node = $(node);
- }
- if (node && node.parentNode) {
- return node.parentNode.removeChild(node);
- }
- else {
- return false;
- }
-}
+Drupal.dimensions = function (el) {
+ return { width: el.offsetWidth, height: el.offsetHeight };
+},
/**
- * Prevents an event from propagating.
+ * Returns the position of the mouse cursor based on the event object passed
*/
-function stopEvent(event) {
- if (event.preventDefault) {
- event.preventDefault();
- event.stopPropagation();
- }
- else {
- event.returnValue = false;
- event.cancelBubble = true;
- }
-}
+Drupal.mousePosition = function(e) {
+ return { x: e.clientX + document.documentElement.scrollLeft, y: e.clientY + document.documentElement.scrollTop };
+},
/**
* Parse a JSON response.
*
* The result is either the JSON object, or an object with 'status' 0 and 'data' an error message.
*/
-function parseJson(data) {
+Drupal.parseJson = function (data) {
if ((data.substring(0, 1) != '{') && (data.substring(0, 1) != '[')) {
return { status: 0, data: data.length ? data : 'Unspecified error' };
}
return eval('(' + data + ');');
-}
+},
/**
* Create an invisible iframe for form submissions.
*/
-function createIframe() {
- // Delete any previous iframe
- deleteIframe();
+Drupal.createIframe = function () {
+ if ($('#redirect-holder').size()) {
+ return;
+ }
// Note: some browsers require the literal name/id attributes on the tag,
// some want them set through JS. We do both.
window.iframeHandler = function () {};
var div = document.createElement('div');
div.id = 'redirect-holder';
- div.innerHTML = '<iframe name="redirect-target" id="redirect-target" class="redirect" onload="window.iframeHandler();"></iframe>';
+ $(div).html('<iframe name="redirect-target" id="redirect-target" class="redirect" onload="window.iframeHandler();"></iframe>');
var iframe = div.firstChild;
- with (iframe) {
- name = 'redirect-target';
- setAttribute('name', 'redirect-target');
- id = 'redirect-target';
- }
- with (iframe.style) {
- position = 'absolute';
- height = '1px';
- width = '1px';
- visibility = 'hidden';
- }
- document.body.appendChild(div);
-}
+ $(iframe)
+ .attr({
+ name: 'redirect-target',
+ id: 'redirect-target'
+ })
+ .css({
+ position: 'absolute',
+ height: '1px',
+ width: '1px',
+ visibility: 'hidden'
+ });
+ $('body').append(div);
+},
/**
- * Delete the invisible iframe for form submissions.
+ * Delete the invisible iframe
*/
-function deleteIframe() {
- var holder = $('redirect-holder');
- if (holder != null) {
- removeNode(holder);
- }
+Drupal.deleteIframe = function () {
+ $('#redirect-holder').remove();
+},
+
+/**
+ * Freeze the current body height (as minimum height). Used to prevent
+ * unnecessary upwards scrolling when doing DOM manipulations.
+ */
+Drupal.freezeHeight = function () {
+ Drupal.unfreezeHeight();
+ var div = document.createElement('div');
+ $(div).css({
+ position: 'absolute',
+ top: '0px',
+ left: '0px',
+ width: '1px',
+ height: $('body').css('height')
+ }).attr('id', 'freeze-height');
+ $('body').append(div);
+},
+
+/**
+ * Unfreeze the body height
+ */
+Drupal.unfreezeHeight = function () {
+ $('#freeze-height').remove();
}
/**
- * Wrapper around document.getElementById().
+ * Wrapper to address the mod_rewrite url encoding bug
+ * (equivalent of drupal_urlencode() in PHP).
*/
-function $(id) {
- return document.getElementById(id);
+Drupal.encodeURIComponent = function (item, uri) {
+ uri = uri || location.href;
+ item = encodeURIComponent(item).replace('%2F', '/');
+ return uri.indexOf('?q=') ? item : item.replace('%26', '%2526').replace('%23', '%2523');
+}
+
+// Global Killswitch on the <html> element
+if (Drupal.jsEnabled) {
+ document.documentElement.className = 'js';
}