webmaster@3: // $Id: drupal.js,v 1.41.2.2 2008/02/27 19:44:44 goba Exp $ webmaster@1: webmaster@1: var Drupal = Drupal || { 'settings': {}, 'behaviors': {}, 'themes': {}, 'locale': {} }; webmaster@1: webmaster@1: /** webmaster@1: * Set the variable that indicates if JavaScript behaviors should be applied webmaster@1: */ webmaster@1: Drupal.jsEnabled = document.getElementsByTagName && document.createElement && document.createTextNode && document.documentElement && document.getElementById; webmaster@1: webmaster@1: /** webmaster@1: * Attach all registered behaviors to a page element. webmaster@1: * webmaster@1: * Behaviors are event-triggered actions that attach to page elements, enhancing webmaster@1: * default non-Javascript UIs. Behaviors are registered in the Drupal.behaviors webmaster@1: * object as follows: webmaster@1: * @code webmaster@1: * Drupal.behaviors.behaviorName = function () { webmaster@1: * ... webmaster@1: * }; webmaster@1: * @endcode webmaster@1: * webmaster@1: * Drupal.attachBehaviors is added below to the jQuery ready event and so webmaster@1: * runs on initial page load. Developers implementing AHAH/AJAX in their webmaster@1: * solutions should also call this function after new page content has been webmaster@1: * loaded, feeding in an element to be processed, in order to attach all webmaster@1: * behaviors to the new content. webmaster@1: * webmaster@1: * Behaviors should use a class in the form behaviorName-processed to ensure webmaster@1: * the behavior is attached only once to a given element. (Doing so enables webmaster@1: * the reprocessing of given elements, which may be needed on occasion despite webmaster@1: * the ability to limit behavior attachment to a particular element.) webmaster@1: * webmaster@1: * @param context webmaster@1: * An element to attach behaviors to. If none is given, the document element webmaster@1: * is used. webmaster@1: */ webmaster@1: Drupal.attachBehaviors = function(context) { webmaster@1: context = context || document; webmaster@1: if (Drupal.jsEnabled) { webmaster@1: // Execute all of them. webmaster@1: jQuery.each(Drupal.behaviors, function() { webmaster@1: this(context); webmaster@1: }); webmaster@1: } webmaster@1: }; webmaster@1: webmaster@1: /** webmaster@1: * Encode special characters in a plain-text string for display as HTML. webmaster@1: */ webmaster@1: Drupal.checkPlain = function(str) { webmaster@1: str = String(str); webmaster@1: var replace = { '&': '&', '"': '"', '<': '<', '>': '>' }; webmaster@1: for (var character in replace) { webmaster@3: var regex = new RegExp(character, 'g'); webmaster@3: str = str.replace(regex, replace[character]); webmaster@1: } webmaster@1: return str; webmaster@1: }; webmaster@1: webmaster@1: /** webmaster@1: * Translate strings to the page language or a given language. webmaster@1: * webmaster@1: * See the documentation of the server-side t() function for further details. webmaster@1: * webmaster@1: * @param str webmaster@1: * A string containing the English string to translate. webmaster@1: * @param args webmaster@1: * An object of replacements pairs to make after translation. Incidences webmaster@1: * of any key in this array are replaced with the corresponding value. webmaster@1: * Based on the first character of the key, the value is escaped and/or themed: webmaster@1: * - !variable: inserted as is webmaster@1: * - @variable: escape plain text to HTML (Drupal.checkPlain) webmaster@1: * - %variable: escape text and theme as a placeholder for user-submitted webmaster@1: * content (checkPlain + Drupal.theme('placeholder')) webmaster@1: * @return webmaster@1: * The translated string. webmaster@1: */ webmaster@1: Drupal.t = function(str, args) { webmaster@1: // Fetch the localized version of the string. webmaster@1: if (Drupal.locale.strings && Drupal.locale.strings[str]) { webmaster@1: str = Drupal.locale.strings[str]; webmaster@1: } webmaster@1: webmaster@1: if (args) { webmaster@1: // Transform arguments before inserting them webmaster@1: for (var key in args) { webmaster@1: switch (key.charAt(0)) { webmaster@1: // Escaped only webmaster@1: case '@': webmaster@1: args[key] = Drupal.checkPlain(args[key]); webmaster@1: break; webmaster@1: // Pass-through webmaster@1: case '!': webmaster@1: break; webmaster@1: // Escaped and placeholder webmaster@1: case '%': webmaster@1: default: webmaster@1: args[key] = Drupal.theme('placeholder', args[key]); webmaster@1: break; webmaster@1: } webmaster@1: str = str.replace(key, args[key]); webmaster@1: } webmaster@1: } webmaster@1: return str; webmaster@1: }; webmaster@1: webmaster@1: /** webmaster@1: * Format a string containing a count of items. webmaster@1: * webmaster@1: * This function ensures that the string is pluralized correctly. Since Drupal.t() is webmaster@1: * called by this function, make sure not to pass already-localized strings to it. webmaster@1: * webmaster@1: * See the documentation of the server-side format_plural() function for further details. webmaster@1: * webmaster@1: * @param count webmaster@1: * The item count to display. webmaster@1: * @param singular webmaster@1: * The string for the singular case. Please make sure it is clear this is webmaster@1: * singular, to ease translation (e.g. use "1 new comment" instead of "1 new"). webmaster@1: * Do not use @count in the singular string. webmaster@1: * @param plural webmaster@1: * The string for the plural case. Please make sure it is clear this is plural, webmaster@1: * to ease translation. Use @count in place of the item count, as in "@count webmaster@1: * new comments". webmaster@1: * @param args webmaster@1: * An object of replacements pairs to make after translation. Incidences webmaster@1: * of any key in this array are replaced with the corresponding value. webmaster@1: * Based on the first character of the key, the value is escaped and/or themed: webmaster@1: * - !variable: inserted as is webmaster@1: * - @variable: escape plain text to HTML (Drupal.checkPlain) webmaster@1: * - %variable: escape text and theme as a placeholder for user-submitted webmaster@1: * content (checkPlain + Drupal.theme('placeholder')) webmaster@1: * Note that you do not need to include @count in this array. webmaster@1: * This replacement is done automatically for the plural case. webmaster@1: * @return webmaster@1: * A translated string. webmaster@1: */ webmaster@1: Drupal.formatPlural = function(count, singular, plural, args) { webmaster@1: var args = args || {}; webmaster@1: args['@count'] = count; webmaster@1: // Determine the index of the plural form. webmaster@1: var index = Drupal.locale.pluralFormula ? Drupal.locale.pluralFormula(args['@count']) : ((args['@count'] == 1) ? 0 : 1); webmaster@1: webmaster@1: if (index == 0) { webmaster@1: return Drupal.t(singular, args); webmaster@1: } webmaster@1: else if (index == 1) { webmaster@1: return Drupal.t(plural, args); webmaster@1: } webmaster@1: else { webmaster@1: args['@count['+ index +']'] = args['@count']; webmaster@1: delete args['@count']; webmaster@1: return Drupal.t(plural.replace('@count', '@count['+ index +']')); webmaster@1: } webmaster@1: }; webmaster@1: webmaster@1: /** webmaster@1: * Generate the themed representation of a Drupal object. webmaster@1: * webmaster@1: * All requests for themed output must go through this function. It examines webmaster@1: * the request and routes it to the appropriate theme function. If the current webmaster@1: * theme does not provide an override function, the generic theme function is webmaster@1: * called. webmaster@1: * webmaster@1: * For example, to retrieve the HTML that is output by theme_placeholder(text), webmaster@1: * call Drupal.theme('placeholder', text). webmaster@1: * webmaster@1: * @param func webmaster@1: * The name of the theme function to call. webmaster@1: * @param ... webmaster@1: * Additional arguments to pass along to the theme function. webmaster@1: * @return webmaster@1: * Any data the theme function returns. This could be a plain HTML string, webmaster@1: * but also a complex object. webmaster@1: */ webmaster@1: Drupal.theme = function(func) { webmaster@1: for (var i = 1, args = []; i < arguments.length; i++) { webmaster@1: args.push(arguments[i]); webmaster@1: } webmaster@1: webmaster@1: return (Drupal.theme[func] || Drupal.theme.prototype[func]).apply(this, args); webmaster@1: }; webmaster@1: webmaster@1: /** webmaster@1: * Parse a JSON response. webmaster@1: * webmaster@1: * The result is either the JSON object, or an object with 'status' 0 and 'data' an error message. webmaster@1: */ webmaster@1: Drupal.parseJson = function (data) { webmaster@1: if ((data.substring(0, 1) != '{') && (data.substring(0, 1) != '[')) { webmaster@1: return { status: 0, data: data.length ? data : Drupal.t('Unspecified error') }; webmaster@1: } webmaster@1: return eval('(' + data + ');'); webmaster@1: }; webmaster@1: webmaster@1: /** webmaster@1: * Freeze the current body height (as minimum height). Used to prevent webmaster@1: * unnecessary upwards scrolling when doing DOM manipulations. webmaster@1: */ webmaster@1: Drupal.freezeHeight = function () { webmaster@1: Drupal.unfreezeHeight(); webmaster@1: var div = document.createElement('div'); webmaster@1: $(div).css({ webmaster@1: position: 'absolute', webmaster@1: top: '0px', webmaster@1: left: '0px', webmaster@1: width: '1px', webmaster@1: height: $('body').css('height') webmaster@1: }).attr('id', 'freeze-height'); webmaster@1: $('body').append(div); webmaster@1: }; webmaster@1: webmaster@1: /** webmaster@1: * Unfreeze the body height webmaster@1: */ webmaster@1: Drupal.unfreezeHeight = function () { webmaster@1: $('#freeze-height').remove(); webmaster@1: }; webmaster@1: webmaster@1: /** webmaster@1: * Wrapper to address the mod_rewrite url encoding bug webmaster@1: * (equivalent of drupal_urlencode() in PHP). webmaster@1: */ webmaster@1: Drupal.encodeURIComponent = function (item, uri) { webmaster@1: uri = uri || location.href; webmaster@1: item = encodeURIComponent(item).replace(/%2F/g, '/'); webmaster@1: return (uri.indexOf('?q=') != -1) ? item : item.replace(/%26/g, '%2526').replace(/%23/g, '%2523').replace(/\/\//g, '/%252F'); webmaster@1: }; webmaster@1: webmaster@1: /** webmaster@1: * Get the text selection in a textarea. webmaster@1: */ webmaster@1: Drupal.getSelection = function (element) { webmaster@1: if (typeof(element.selectionStart) != 'number' && document.selection) { webmaster@1: // The current selection webmaster@1: var range1 = document.selection.createRange(); webmaster@1: var range2 = range1.duplicate(); webmaster@1: // Select all text. webmaster@1: range2.moveToElementText(element); webmaster@1: // Now move 'dummy' end point to end point of original range. webmaster@1: range2.setEndPoint('EndToEnd', range1); webmaster@1: // Now we can calculate start and end points. webmaster@1: var start = range2.text.length - range1.text.length; webmaster@1: var end = start + range1.text.length; webmaster@1: return { 'start': start, 'end': end }; webmaster@1: } webmaster@1: return { 'start': element.selectionStart, 'end': element.selectionEnd }; webmaster@1: }; webmaster@1: webmaster@1: /** webmaster@1: * Build an error message from ahah response. webmaster@1: */ webmaster@1: Drupal.ahahError = function(xmlhttp, uri) { webmaster@1: if (xmlhttp.status == 200) { webmaster@1: if (jQuery.trim($(xmlhttp.responseText).text())) { webmaster@1: var message = Drupal.t("An error occurred. \n@uri\n@text", {'@uri': uri, '@text': xmlhttp.responseText }); webmaster@1: } webmaster@1: else { webmaster@1: var message = Drupal.t("An error occurred. \n@uri\n(no information available).", {'@uri': uri, '@text': xmlhttp.responseText }); webmaster@1: } webmaster@1: } webmaster@1: else { webmaster@1: var message = Drupal.t("An HTTP error @status occurred. \n@uri", {'@uri': uri, '@status': xmlhttp.status }); webmaster@1: } webmaster@1: return message; webmaster@1: } webmaster@1: webmaster@1: // Global Killswitch on the element webmaster@1: if (Drupal.jsEnabled) { webmaster@1: // Global Killswitch on the element webmaster@1: document.documentElement.className = 'js'; webmaster@1: // 'js enabled' cookie webmaster@1: document.cookie = 'has_js=1; path=/'; webmaster@1: // Attach all behaviors. webmaster@1: $(document).ready(function() { webmaster@1: Drupal.attachBehaviors(this); webmaster@1: }); webmaster@1: } webmaster@1: webmaster@1: /** webmaster@1: * The default themes. webmaster@1: */ webmaster@1: Drupal.theme.prototype = { webmaster@1: webmaster@1: /** webmaster@1: * Formats text for emphasized display in a placeholder inside a sentence. webmaster@1: * webmaster@1: * @param str webmaster@1: * The text to format (plain-text). webmaster@1: * @return webmaster@1: * The formatted text (html). webmaster@1: */ webmaster@1: placeholder: function(str) { webmaster@1: return '' + Drupal.checkPlain(str) + ''; webmaster@1: } webmaster@1: };