diff --git a/CHANGELOG.txt b/CHANGELOG.txt index e5ed11d1aa89591e97cc9d9a058e9296f69e09a4..f2dc215bae94e1472e8c058cea2471333830257f 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -61,6 +61,7 @@ Drupal 6.0, xxxx-xx-xx (development version) - Added support for configurable actions. - Made user profiles easier to theme by using array rendering and supplying template files. - Added Deletion API to allow modules to alter and respond to any delete operation. +- Added the Update status module to automatically check for available updates and warn sites if they are missing security updates or newer versions. Drupal 5.0, 2007-01-15 ---------------------- diff --git a/misc/autocomplete.js b/misc/autocomplete.js index 2431d37e422760180c5d6b76321968068496484c..844b628cc4c21cb5f4e365279186a59084db8075 100644 --- a/misc/autocomplete.js +++ b/misc/autocomplete.js @@ -3,9 +3,9 @@ /** * Attaches the autocomplete behaviour to all required fields */ -Drupal.autocompleteAutoAttach = function () { +Drupal.behaviors.autocomplete = function (context) { var acdb = []; - $('input.autocomplete').each(function () { + $('input.autocomplete:not(.autocomplete-processed)', context).each(function () { var uri = this.value; if (!acdb[uri]) { acdb[uri] = new Drupal.ACDB(uri); @@ -14,6 +14,7 @@ Drupal.autocompleteAutoAttach = function () { .attr('autocomplete', 'OFF')[0]; $(input.form).submit(Drupal.autocompleteSubmit); new Drupal.jsAC(input, acdb[uri]); + $(this).addClass('autocomplete-processed'); }); }; @@ -296,8 +297,3 @@ Drupal.ACDB.prototype.cancel = function() { if (this.timer) clearTimeout(this.timer); this.searchString = ''; }; - -// Global Killswitch -if (Drupal.jsEnabled) { - $(document).ready(Drupal.autocompleteAutoAttach); -} diff --git a/misc/batch.js b/misc/batch.js index 8cf1f910f69123aec6772935f144475109c8c523..51b1e8b59c390aa3b54b80d97f84ee806549d2c2 100644 --- a/misc/batch.js +++ b/misc/batch.js @@ -1,31 +1,38 @@ -if (Drupal.jsEnabled) { - $(document).ready(function() { - $('#progress').each(function () { - var holder = this; - var uri = Drupal.settings.batch.uri; - var initMessage = Drupal.settings.batch.initMessage; - var errorMessage = Drupal.settings.batch.errorMessage; +// $Id$ - // Success: redirect to the summary. - var updateCallback = function (progress, status, pb) { - if (progress == 100) { - pb.stopMonitoring(); - window.location = uri+'&op=finished'; - } - }; +/** + * Attaches the batch behaviour to progress bars. + */ +Drupal.behaviors.batch = function (context) { + // This behavior attaches by ID, so is only valid once on a page. + if ($('#progress.batch-processed').size()) { + return; + } + $('#progress', context).addClass('batch-processed').each(function () { + var holder = this; + var uri = Drupal.settings.batch.uri; + var initMessage = Drupal.settings.batch.initMessage; + var errorMessage = Drupal.settings.batch.errorMessage; - var errorCallback = function (pb) { - var div = document.createElement('p'); - div.className = 'error'; - $(div).html(errorMessage); - $(holder).prepend(div); - $('#wait').hide(); - }; + // Success: redirect to the summary. + var updateCallback = function (progress, status, pb) { + if (progress == 100) { + pb.stopMonitoring(); + window.location = uri+'&op=finished'; + } + }; - var progress = new Drupal.progressBar('updateprogress', updateCallback, "POST", errorCallback); - progress.setProgress(-1, initMessage); - $(holder).append(progress.element); - progress.startMonitoring(uri+'&op=do', 10); - }); + var errorCallback = function (pb) { + var div = document.createElement('p'); + div.className = 'error'; + $(div).html(errorMessage); + $(holder).prepend(div); + $('#wait').hide(); + }; + + var progress = new Drupal.progressBar('updateprogress', updateCallback, "POST", errorCallback); + progress.setProgress(-1, initMessage); + $(holder).append(progress.element); + progress.startMonitoring(uri+'&op=do', 10); }); -} +}; diff --git a/misc/collapse.js b/misc/collapse.js index c1fd3d4c32b43b0d303be02dd97c2d5e85171b30..7bff25397f5af5f79e840b1f0eef3f28388082b1 100644 --- a/misc/collapse.js +++ b/misc/collapse.js @@ -20,10 +20,6 @@ Drupal.toggleFieldset = function(fieldset) { Drupal.collapseScrollIntoView(this.parentNode); } }); - if (typeof(Drupal.textareaAttach) != 'undefined') { - // Initialize resizable textareas that are now revealed - Drupal.textareaAttach(null, fieldset); - } } else { var content = $('> div', fieldset).slideUp('medium', function() { @@ -50,19 +46,17 @@ Drupal.collapseScrollIntoView = function (node) { } }; -// Global Killswitch -if (Drupal.jsEnabled) { - $(document).ready(function() { - $('fieldset.collapsible > legend').each(function() { - var fieldset = $(this.parentNode); - // Expand if there are errors inside - if ($('input.error, textarea.error, select.error', fieldset).size() > 0) { - fieldset.removeClass('collapsed'); - } +Drupal.behaviors.collapse = function (context) { + $('fieldset.collapsible > legend:not(.collapse-processed)', context).each(function() { + var fieldset = $(this.parentNode); + // Expand if there are errors inside + if ($('input.error, textarea.error, select.error', fieldset).size() > 0) { + fieldset.removeClass('collapsed'); + } - // Turn the legend into a clickable link and wrap the contents of the fieldset - // in a div for easier animation - var text = this.innerHTML; + // Turn the legend into a clickable link and wrap the contents of the fieldset + // in a div for easier animation + var text = this.innerHTML; $(this).empty().append($('<a href="#">'+ text +'</a>').click(function() { var fieldset = $(this).parents('fieldset:first')[0]; // Don't animate multiple times @@ -71,7 +65,9 @@ if (Drupal.jsEnabled) { Drupal.toggleFieldset(fieldset); } return false; - })).after($('<div class="fieldset-wrapper"></div>').append(fieldset.children(':not(legend)'))); - }); + })) + .after($('<div class="fieldset-wrapper"></div>') + .append(fieldset.children(':not(legend)'))) + .addClass('collapse-processed'); }); -} +}; diff --git a/misc/drupal.js b/misc/drupal.js index 98441c7ecb3a2f8abea5bd14182f84e41610e41c..0c155f7d6e15818dca30bf7f8a8b8d319ab7a7f0 100644 --- a/misc/drupal.js +++ b/misc/drupal.js @@ -1,6 +1,6 @@ // $Id$ -var Drupal = Drupal || { 'settings': {}, 'themes': {}, 'locale': {} }; +var Drupal = Drupal || { 'settings': {}, 'behaviors': {}, 'themes': {}, 'locale': {} }; /** * Set the variable that indicates if JavaScript behaviors should be applied @@ -21,6 +21,43 @@ Drupal.extend = function(obj) { } }; +/** + * Attach all registered behaviors to a page element. + * + * Behaviors are event-triggered actions that attach to page elements, enhancing + * default non-Javascript UIs. Behaviors are registered in the Drupal.behaviors + * object as follows: + * @code + * Drupal.behaviors.behaviorName = function () { + * ... + * }; + * @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. + * + * Behaviors should use a class in the form behaviorName-processed 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 despite + * the ability to limit behavior attachment to a particular element.) + * + * @param context + * An element to attach behaviors to. If none is given, the document element + * is used. + */ +Drupal.attachBehaviors = function(context) { + context = context || document; + if (Drupal.jsEnabled) { + // Execute all of them. + jQuery.each(Drupal.behaviors, function() { + this(context); + }); + } +}; + /** * Encode special characters in a plain-text string for display as HTML. */ @@ -362,6 +399,8 @@ if (Drupal.jsEnabled) { document.documentElement.className = 'js'; // 'js enabled' cookie document.cookie = 'has_js=1'; + // Attach all behaviors. + $(document).ready(Drupal.attachBehaviors); } /** diff --git a/misc/tableheader.js b/misc/tableheader.js index 5b84126ca4f0c73f7940d38f2ba00300f0368bd4..80d1fbddeefb5ae5277821e022ffd3a4fdb7b98f 100644 --- a/misc/tableheader.js +++ b/misc/tableheader.js @@ -1,60 +1,57 @@ // $Id$ -// Global Killswitch -if (Drupal.jsEnabled) { +Drupal.behaviors.tableHeader = function (context) { // Keep track of all header cells. var cells = []; - // Attach to all headers. - $(document).ready(function() { - var z = 0; - $('table thead').each(function () { - // Find table height. - var table = $(this).parent('table')[0]; - var height = $(table).addClass('sticky-table').height(); - var i = 0; + var z = 0; + $('table thead:not(.tableHeader-processed)', context).each(function () { + // Find table height. + var table = $(this).parent('table')[0]; + var height = $(table).addClass('sticky-table').height(); + var i = 0; - // Find all header cells. - $('th', this).each(function () { + // Find all header cells. + $('th', this).each(function () { - // Ensure each cell has an element in it. - var html = $(this).html(); - if (html == ' ') { - html = ' '; - } - if ($(this).children().size() == 0) { - html = '<span>'+ html +'</span>'; - } + // Ensure each cell has an element in it. + var html = $(this).html(); + if (html == ' ') { + html = ' '; + } + if ($(this).children().size() == 0) { + html = '<span>'+ html +'</span>'; + } - // Clone and wrap cell contents in sticky wrapper that overlaps the cell's padding. - $('<div class="sticky-header" style="position: fixed; visibility: hidden; top: 0px;">'+ html +'</div>').prependTo(this); - var div = $('div.sticky-header', this).css({ - 'marginLeft': '-'+ $(this).css('paddingLeft'), - 'marginRight': '-'+ $(this).css('paddingRight'), - 'paddingLeft': $(this).css('paddingLeft'), - 'paddingTop': $(this).css('paddingTop'), - 'paddingBottom': $(this).css('paddingBottom'), - 'z-index': ++z - })[0]; - cells.push(div); + // Clone and wrap cell contents in sticky wrapper that overlaps the cell's padding. + $('<div class="sticky-header" style="position: fixed; visibility: hidden; top: 0px;">'+ html +'</div>').prependTo(this); + var div = $('div.sticky-header', this).css({ + 'marginLeft': '-'+ $(this).css('paddingLeft'), + 'marginRight': '-'+ $(this).css('paddingRight'), + 'paddingLeft': $(this).css('paddingLeft'), + 'paddingTop': $(this).css('paddingTop'), + 'paddingBottom': $(this).css('paddingBottom'), + 'z-index': ++z + })[0]; + cells.push(div); - // Adjust width to fit cell/table. - var ref = this; - if (!i++) { - // The first cell is as wide as the table to prevent gaps. - ref = table; - div.wide = true; - } - $(div).css('width', parseInt($(ref).width()) - - parseInt($(div).css('paddingLeft')) +'px'); + // Adjust width to fit cell/table. + var ref = this; + if (!i++) { + // The first cell is as wide as the table to prevent gaps. + ref = table; + div.wide = true; + } + $(div).css('width', parseInt($(ref).width()) + - parseInt($(div).css('paddingLeft')) +'px'); - // Get position and store. - div.cell = this; - div.table = table; - div.stickyMax = height; - div.stickyPosition = Drupal.absolutePosition(this).y; - }); + // Get position and store. + div.cell = this; + div.table = table; + div.stickyMax = height; + div.stickyPosition = Drupal.absolutePosition(this).y; }); + $(this).addClass('tableHeader-processed'); }); // Track scrolling. @@ -108,4 +105,4 @@ if (Drupal.jsEnabled) { }, 250); }; $(window).resize(resize); -} +}; diff --git a/misc/tableselect.js b/misc/tableselect.js index 5c0cfbb323aa69c69f60f4d2aa9ae10e96e45718..978cff7c25c7589c629657f338df9e63d1d2a377 100644 --- a/misc/tableselect.js +++ b/misc/tableselect.js @@ -1,5 +1,9 @@ // $Id$ +Drupal.behaviors.tableSelect = function (context) { + $('form table[th.select-all]:not(.tableSelect-processed)', context).each(Drupal.tableSelect); +} + Drupal.tableSelect = function() { // Keep track of the table, which checkbox is checked and alias the settings. var table = this, selectAll, checkboxes, lastChecked; @@ -41,6 +45,7 @@ Drupal.tableSelect = function() { // Keep track of the last checked checkbox. lastChecked = e.target; }); + $(this).addClass('tableSelect-processed'); }; Drupal.tableSelectRange = function(from, to, state) { @@ -67,10 +72,3 @@ Drupal.tableSelectRange = function(from, to, state) { } }; - -// Global Killswitch -if (Drupal.jsEnabled) { - $(document).ready(function() { - $('form table[th.select-all]').each(Drupal.tableSelect); - }); -} diff --git a/misc/teaser.js b/misc/teaser.js index c59a92e55fdad1d49898e1bd0fd246c1800f23c7..0aa512901c116ba598c9966b42a17301a3a9820d 100644 --- a/misc/teaser.js +++ b/misc/teaser.js @@ -5,9 +5,9 @@ * * Note: depends on resizable textareas. */ -Drupal.teaserAttach = function() { - $('textarea.teaser:not(.joined)').each(function() { - var teaser = $(this).addClass('joined'); +Drupal.behaviors.teaser = function(context) { + $('textarea.teaser:not(.teaser-processed)', context).each(function() { + var teaser = $(this).addClass('teaser-processed'); // Move teaser textarea before body, and remove its form-item wrapper. var body = $('#'+ Drupal.settings.teaser[this.id]); @@ -75,7 +75,3 @@ Drupal.teaserAttach = function() { }); }; - -if (Drupal.jsEnabled) { - $(document).ready(Drupal.teaserAttach); -} diff --git a/misc/textarea.js b/misc/textarea.js index 9cd5a1c8499928fab7691fc853c3047e6a7d7209..65b8d3cca6fc43579d08ab190a0cf34da6a3c6df 100644 --- a/misc/textarea.js +++ b/misc/textarea.js @@ -1,8 +1,8 @@ // $Id$ -Drupal.textareaAttach = function() { - $('textarea.resizable:not(.processed)').each(function() { - var textarea = $(this).addClass('processed'), staticOffset = null; +Drupal.behaviors.textarea = function(context) { + $('textarea.resizable:not(.textarea-processed)', context).each(function() { + var textarea = $(this).addClass('textarea-processed'), staticOffset = null; // When wrapping the text area, work around an IE margin bug. See: // http://jaspan.com/ie-inherited-margin-bug-form-elements-and-haslayout @@ -37,7 +37,3 @@ Drupal.textareaAttach = function() { } }); }; - -if (Drupal.jsEnabled) { - $(document).ready(Drupal.textareaAttach); -} diff --git a/misc/upload.js b/misc/upload.js index 900d979ece7764a0c223f83c75267eba16fb7c76..d69f3b7656ca9a189ff6c65abd3c39e1d2e79e53 100644 --- a/misc/upload.js +++ b/misc/upload.js @@ -3,8 +3,8 @@ /** * Attaches the upload behaviour to the upload form. */ -Drupal.uploadAutoAttach = function() { - $('input.upload').each(function () { +Drupal.behaviors.upload = function(context) { + $('input.upload:not(.upload-processed)', context).addClass('upload-processed').each(function () { var uri = this.value; // Extract the base name from the id (edit-attach-url -> attach). var base = this.id.substring(5, this.id.length - 4); @@ -12,6 +12,7 @@ Drupal.uploadAutoAttach = function() { var wrapper = base + '-wrapper'; var hide = base + '-hide'; var upload = new Drupal.jsUpload(uri, button, wrapper, hide); + $(this).addClass('upload-processed'); }); }; @@ -65,11 +66,10 @@ Drupal.jsUpload.prototype.oncomplete = function (data) { // If uploading the first attachment fade in everything if ($('tr', div).size() == 2) { - // Replace form and re-attach behaviour + // Replace form and re-attach behaviours $(div).hide(); $(this.wrapper).append(div); $(div).fadeIn('slow'); - Drupal.uploadAutoAttach(); } // Else fade in only the last table row else { @@ -89,8 +89,8 @@ Drupal.jsUpload.prototype.oncomplete = function (data) { $(this.wrapper).append(div); $('table tr:last-of-type td', div).fadeIn('slow'); $(this.hide, div).fadeIn('slow'); - Drupal.uploadAutoAttach(); } + Drupal.attachBehaviors(div); Drupal.unfreezeHeight(); }; @@ -108,9 +108,3 @@ Drupal.jsUpload.prototype.onerror = function (error) { left: '0px' }); }; - - -// Global killswitch -if (Drupal.jsEnabled) { - $(document).ready(Drupal.uploadAutoAttach); -} diff --git a/modules/actions/actions.schema b/modules/actions/actions.schema index 2e2ca9b28fbb8a42b73d6f2ca05c27fa3db38075..516e2ced3c416be7e8e86fde63441621e299f1ec 100644 --- a/modules/actions/actions.schema +++ b/modules/actions/actions.schema @@ -7,7 +7,7 @@ function actions_schema() { 'aid' => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => '0'), 'type' => array('type' => 'varchar', 'length' => 32, 'not null' => TRUE, 'default' => ''), 'callback' => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''), - 'parameters' => array('type' => 'text', 'not null' => TRUE, 'size' => 'big', 'default' => ''), + 'parameters' => array('type' => 'text', 'not null' => TRUE, 'size' => 'big'), 'description' => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => '0'), ), 'primary key' => array('aid'), diff --git a/modules/color/color.js b/modules/color/color.js index cb76ffabbc5d696cb3b0c73e5612667f04819be5..c64f41481c83b53b2a79ddc1b6e8eb476d1f2364 100644 --- a/modules/color/color.js +++ b/modules/color/color.js @@ -1,247 +1,251 @@ // $Id$ -if (Drupal.jsEnabled) { - $(document).ready(function () { - var form = $('#color_scheme_form .color-form'); - var inputs = []; - var hooks = []; - var locks = []; - var focused = null; - - // Add Farbtastic - $(form).prepend('<div id="placeholder"></div>'); - var farb = $.farbtastic('#placeholder'); - - // Decode reference colors to HSL - var reference = Drupal.settings.color.reference; - for (i in reference) { - reference[i] = farb.RGBToHSL(farb.unpack(reference[i])); - } - - // Build preview - $('#preview').append('<div id="gradient"></div>'); - var gradient = $('#preview #gradient'); - var h = parseInt(gradient.css('height')) / 10; - for (i = 0; i < h; ++i) { - gradient.append('<div class="gradient-line"></div>'); - } - - // Fix preview background in IE6 - if (navigator.appVersion.match(/MSIE [0-6]\./)) { - var e = $('#preview #img')[0]; - var image = e.currentStyle.backgroundImage; - e.style.backgroundImage = 'none'; - e.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src='" + image.substring(5, image.length - 2) + "')"; +Drupal.behaviors.color = function (context) { + // This behavior attaches by ID, so is only valid once on a page. + if ($('#color_scheme_form .color-form.color-processed').size()) { + return; + } + var form = $('#color_scheme_form .color-form', context); + var inputs = []; + var hooks = []; + var locks = []; + var focused = null; + + // Add Farbtastic + $(form).prepend('<div id="placeholder"></div>').addClass('color-processed'); + var farb = $.farbtastic('#placeholder'); + + // Decode reference colors to HSL + var reference = Drupal.settings.color.reference; + for (i in reference) { + reference[i] = farb.RGBToHSL(farb.unpack(reference[i])); + } + + // Build preview + $('#preview:not(.color-processed)') + .append('<div id="gradient"></div>') + .addClass('color-processed'); + var gradient = $('#preview #gradient'); + var h = parseInt(gradient.css('height')) / 10; + for (i = 0; i < h; ++i) { + gradient.append('<div class="gradient-line"></div>'); + } + + // Fix preview background in IE6 + if (navigator.appVersion.match(/MSIE [0-6]\./)) { + var e = $('#preview #img')[0]; + var image = e.currentStyle.backgroundImage; + e.style.backgroundImage = 'none'; + e.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src='" + image.substring(5, image.length - 2) + "')"; + } + + // Set up colorscheme selector + $('#edit-scheme', form).change(function () { + var colors = this.options[this.selectedIndex].value; + if (colors != '') { + colors = colors.split(','); + for (i in colors) { + callback(inputs[i], colors[i], false, true); + } + preview(); } + }); - // Set up colorscheme selector - $('#edit-scheme', form).change(function () { - var colors = this.options[this.selectedIndex].value; - if (colors != '') { - colors = colors.split(','); - for (i in colors) { - callback(inputs[i], colors[i], false, true); - } - preview(); + /** + * Render the preview. + */ + function preview() { + // Solid background + $('#preview', form).css('backgroundColor', inputs[0].value); + + // Text preview + $('#text', form).css('color', inputs[4].value); + $('#text a, #text h2', form).css('color', inputs[1].value); + + // Set up gradient + var top = farb.unpack(inputs[2].value); + var bottom = farb.unpack(inputs[3].value); + if (top && bottom) { + var delta = []; + for (i in top) { + delta[i] = (bottom[i] - top[i]) / h; } - }); + var accum = top; - /** - * Render the preview. - */ - function preview() { - // Solid background - $('#preview', form).css('backgroundColor', inputs[0].value); - - // Text preview - $('#text', form).css('color', inputs[4].value); - $('#text a, #text h2', form).css('color', inputs[1].value); - - // Set up gradient - var top = farb.unpack(inputs[2].value); - var bottom = farb.unpack(inputs[3].value); - if (top && bottom) { - var delta = []; - for (i in top) { - delta[i] = (bottom[i] - top[i]) / h; + // Render gradient lines + $('#gradient > div', form).each(function () { + for (i in accum) { + accum[i] += delta[i]; } - var accum = top; - - // Render gradient lines - $('#gradient > div', form).each(function () { - for (i in accum) { - accum[i] += delta[i]; - } - this.style.backgroundColor = farb.pack(accum); - }); - } + this.style.backgroundColor = farb.pack(accum); + }); } - - /** - * Shift a given color, using a reference pair (ref in HSL). - * - * This algorithm ensures relative ordering on the saturation and luminance - * axes is preserved, and performs a simple hue shift. - * - * It is also symmetrical. If: shift_color(c, a, b) == d, - * then shift_color(d, b, a) == c. - */ - function shift_color(given, ref1, ref2) { - // Convert to HSL - given = farb.RGBToHSL(farb.unpack(given)); - - // Hue: apply delta - given[0] += ref2[0] - ref1[0]; - - // Saturation: interpolate - if (ref1[1] == 0 || ref2[1] == 0) { - given[1] = ref2[1]; + } + + /** + * Shift a given color, using a reference pair (ref in HSL). + * + * This algorithm ensures relative ordering on the saturation and luminance + * axes is preserved, and performs a simple hue shift. + * + * It is also symmetrical. If: shift_color(c, a, b) == d, + * then shift_color(d, b, a) == c. + */ + function shift_color(given, ref1, ref2) { + // Convert to HSL + given = farb.RGBToHSL(farb.unpack(given)); + + // Hue: apply delta + given[0] += ref2[0] - ref1[0]; + + // Saturation: interpolate + if (ref1[1] == 0 || ref2[1] == 0) { + given[1] = ref2[1]; + } + else { + var d = ref1[1] / ref2[1]; + if (d > 1) { + given[1] /= d; } else { - var d = ref1[1] / ref2[1]; - if (d > 1) { - given[1] /= d; - } - else { - given[1] = 1 - (1 - given[1]) * d; - } + given[1] = 1 - (1 - given[1]) * d; } + } - // Luminance: interpolate - if (ref1[2] == 0 || ref2[2] == 0) { - given[2] = ref2[2]; + // Luminance: interpolate + if (ref1[2] == 0 || ref2[2] == 0) { + given[2] = ref2[2]; + } + else { + var d = ref1[2] / ref2[2]; + if (d > 1) { + given[2] /= d; } else { - var d = ref1[2] / ref2[2]; - if (d > 1) { - given[2] /= d; - } - else { - given[2] = 1 - (1 - given[2]) * d; - } + given[2] = 1 - (1 - given[2]) * d; } - - return farb.pack(farb.HSLToRGB(given)); } - /** - * Callback for Farbtastic when a new color is chosen. - */ - function callback(input, color, propagate, colorscheme) { - // Set background/foreground color - $(input).css({ - backgroundColor: color, - 'color': farb.RGBToHSL(farb.unpack(color))[2] > 0.5 ? '#000' : '#fff' - }); + return farb.pack(farb.HSLToRGB(given)); + } + + /** + * Callback for Farbtastic when a new color is chosen. + */ + function callback(input, color, propagate, colorscheme) { + // Set background/foreground color + $(input).css({ + backgroundColor: color, + 'color': farb.RGBToHSL(farb.unpack(color))[2] > 0.5 ? '#000' : '#fff' + }); - // Change input value - if (input.value && input.value != color) { - input.value = color; - - // Update locked values - if (propagate) { - var i = input.i; - for (j = i + 1; ; ++j) { - if (!locks[j - 1] || $(locks[j - 1]).is('.unlocked')) break; - var matched = shift_color(color, reference[input.key], reference[inputs[j].key]); - callback(inputs[j], matched, false); - } - for (j = i - 1; ; --j) { - if (!locks[j] || $(locks[j]).is('.unlocked')) break; - var matched = shift_color(color, reference[input.key], reference[inputs[j].key]); - callback(inputs[j], matched, false); - } - - // Update preview - preview(); + // Change input value + if (input.value && input.value != color) { + input.value = color; + + // Update locked values + if (propagate) { + var i = input.i; + for (j = i + 1; ; ++j) { + if (!locks[j - 1] || $(locks[j - 1]).is('.unlocked')) break; + var matched = shift_color(color, reference[input.key], reference[inputs[j].key]); + callback(inputs[j], matched, false); } - - // Reset colorscheme selector - if (!colorscheme) { - resetScheme(); + for (j = i - 1; ; --j) { + if (!locks[j] || $(locks[j]).is('.unlocked')) break; + var matched = shift_color(color, reference[input.key], reference[inputs[j].key]); + callback(inputs[j], matched, false); } - } - } + // Update preview + preview(); + } - /** - * Reset the color scheme selector. - */ - function resetScheme() { - $('#edit-scheme', form).each(function () { - this.selectedIndex = this.options.length - 1; - }); + // Reset colorscheme selector + if (!colorscheme) { + resetScheme(); + } } - // Focus the Farbtastic on a particular field. - function focus() { - var input = this; - // Remove old bindings - focused && $(focused).unbind('keyup', farb.updateValue) - .unbind('keyup', preview).unbind('keyup', resetScheme) - .parent().removeClass('item-selected'); - - // Add new bindings - focused = this; - farb.linkTo(function (color) { callback(input, color, true, false) }); - farb.setColor(this.value); - $(focused).keyup(farb.updateValue).keyup(preview).keyup(resetScheme) - .parent().addClass('item-selected'); - } + } - // Initialize color fields - $('#palette input.form-text', form) - .each(function () { - // Extract palette field name - this.key = this.id.substring(13); - - // Link to color picker temporarily to initialize. - farb.linkTo(function () {}).setColor('#000').linkTo(this); - - // Add lock - var i = inputs.length; - if (inputs.length) { - var lock = $('<div class="lock"></div>').toggle( - function () { - $(this).addClass('unlocked'); - $(hooks[i - 1]).attr('class', - locks[i - 2] && $(locks[i - 2]).is(':not(.unlocked)') ? 'hook up' : 'hook' - ); - $(hooks[i]).attr('class', - locks[i] && $(locks[i]).is(':not(.unlocked)') ? 'hook down' : 'hook' - ); - }, - function () { - $(this).removeClass('unlocked'); - $(hooks[i - 1]).attr('class', - locks[i - 2] && $(locks[i - 2]).is(':not(.unlocked)') ? 'hook both' : 'hook down' - ); - $(hooks[i]).attr('class', - locks[i] && $(locks[i]).is(':not(.unlocked)') ? 'hook both' : 'hook up' - ); - } - ); - $(this).after(lock); - locks.push(lock); - }; - - // Add hook - var hook = $('<div class="hook"></div>'); - $(this).after(hook); - hooks.push(hook); - - $(this).parent().find('.lock').click(); - this.i = i; - inputs.push(this); - }) - .focus(focus); - - $('#palette label', form); - - // Focus first color - focus.call(inputs[0]); - - // Render preview - preview(); - }); -} + /** + * Reset the color scheme selector. + */ + function resetScheme() { + $('#edit-scheme', form).each(function () { + this.selectedIndex = this.options.length - 1; + }); + } + + // Focus the Farbtastic on a particular field. + function focus() { + var input = this; + // Remove old bindings + focused && $(focused).unbind('keyup', farb.updateValue) + .unbind('keyup', preview).unbind('keyup', resetScheme) + .parent().removeClass('item-selected'); + + // Add new bindings + focused = this; + farb.linkTo(function (color) { callback(input, color, true, false) }); + farb.setColor(this.value); + $(focused).keyup(farb.updateValue).keyup(preview).keyup(resetScheme) + .parent().addClass('item-selected'); + } + + // Initialize color fields + $('#palette input.form-text', form) + .each(function () { + // Extract palette field name + this.key = this.id.substring(13); + + // Link to color picker temporarily to initialize. + farb.linkTo(function () {}).setColor('#000').linkTo(this); + + // Add lock + var i = inputs.length; + if (inputs.length) { + var lock = $('<div class="lock"></div>').toggle( + function () { + $(this).addClass('unlocked'); + $(hooks[i - 1]).attr('class', + locks[i - 2] && $(locks[i - 2]).is(':not(.unlocked)') ? 'hook up' : 'hook' + ); + $(hooks[i]).attr('class', + locks[i] && $(locks[i]).is(':not(.unlocked)') ? 'hook down' : 'hook' + ); + }, + function () { + $(this).removeClass('unlocked'); + $(hooks[i - 1]).attr('class', + locks[i - 2] && $(locks[i - 2]).is(':not(.unlocked)') ? 'hook both' : 'hook down' + ); + $(hooks[i]).attr('class', + locks[i] && $(locks[i]).is(':not(.unlocked)') ? 'hook both' : 'hook up' + ); + } + ); + $(this).after(lock); + locks.push(lock); + }; + + // Add hook + var hook = $('<div class="hook"></div>'); + $(this).after(hook); + hooks.push(hook); + + $(this).parent().find('.lock').click(); + this.i = i; + inputs.push(this); + }) + .focus(focus); + + $('#palette label', form); + + // Focus first color + focus.call(inputs[0]); + + // Render preview + preview(); +}; diff --git a/modules/comment/comment.js b/modules/comment/comment.js index 96ecbaf5de89f540e77e741474fbd0ffde898efb..69baf7423e16a354b0a8c48532137f5ad48017cc 100644 --- a/modules/comment/comment.js +++ b/modules/comment/comment.js @@ -1,15 +1,16 @@ // $Id$ -if (Drupal.jsEnabled) { - $(document).ready(function() { - var parts = new Array("name", "homepage", "mail"); - var cookie = ''; - for (i=0;i<3;i++) { - cookie = Drupal.comment.getCookie('comment_info_' + parts[i]); - if (cookie != '') { - $("#comment-form input[@name=" + parts[i] + "]").val(cookie); - } + +Drupal.behaviors.comment = function (context) { + var parts = new Array("name", "homepage", "mail"); + var cookie = ''; + for (i=0;i<3;i++) { + cookie = Drupal.comment.getCookie('comment_info_' + parts[i]); + if (cookie != '') { + $("#comment-form input[@name=" + parts[i] + "]:not(.comment-processed)", context) + .val(cookie) + .addClass('comment-processed'); } - }); + } }; Drupal.comment = {}; diff --git a/modules/locale/locale.module b/modules/locale/locale.module index c889241e79b6b92f934fb60daf3f390efa88797b..f0ab4865047dd4835e1aaac4b79246014daeaa45 100644 --- a/modules/locale/locale.module +++ b/modules/locale/locale.module @@ -53,7 +53,7 @@ function locale_help($path, $arg) { return '<p>'. t("This page allows you to export Drupal strings. The first option is to export a translation so it can be shared. The second option generates a translation template, which contains all Drupal strings, but without their translations. You can use this template to start a new translation using various software packages designed for this task.") .'</p>'; case 'admin/build/translate/search': return '<p>'. t("It is often convenient to get the strings from your setup on the <a href=\"@export\">export page</a>, and use a desktop Gettext translation editor to edit the translations. On this page you can search in the translated and untranslated strings, and the default English texts provided by Drupal.", array("@export" => url("admin/build/translate/export"))) .'</p>'; - + case 'admin/build/block/configure': if ($arg[4] == 'locale' && $arg[5] == 0) { return '<p>'. t("This block is only shown if you have <a href=\"@languages\">at least two languages enabled</a> and you have a <a href=\"@configuration\">language negotiation setting</a> different from 'none', so you have different web addresses for different language versions.", array('@languages' => url('admin/settings/language'), '@configuration' => url('admin/settings/language/configure'))) .'</p>'; @@ -524,13 +524,13 @@ function locale_block($op = 'list', $delta = 0) { 'attributes' => array('class' => 'language-link'), ); } - + // Allow modules to provide translations for specific links. // A translation link may need to point to a different path or use // a translated link text before going through l(), which will just // handle the path aliases. drupal_alter('translation_link', $links, $_GET['q']); - + $block['subject'] = t('Languages'); $block['content'] = theme('links', $links, array()); return $block; diff --git a/modules/openid/openid.js b/modules/openid/openid.js index 5f27b66f5dd962f40c98cdee1c0f9c0b8fc41150..688ba47c5f538a706567a3cd440504ec6d41c0ef 100644 --- a/modules/openid/openid.js +++ b/modules/openid/openid.js @@ -1,14 +1,17 @@ // $Id$ -$(document).ready( - function() { - if ($("#edit-openid-url").val()) { - $("#edit-name-wrapper").hide(); - $("#edit-pass-wrapper").hide(); - $("#edit-openid-url-wrapper").show(); - $("a.openid-link").hide(); - } - $("a.openid-link").click( function() { +Drupal.behaviors.openid = function (context) { + // This behavior attaches by ID, so is only valid once on a page. + if (!$("#edit-openid-url.openid-processed").size() && $("#edit-openid-url").val()) { + $("#edit-openid-url").addClass('openid-processed'); + $("#edit-name-wrapper").hide(); + $("#edit-pass-wrapper").hide(); + $("#edit-openid-url-wrapper").show(); + $("a.openid-link").hide(); + } + $("a.openid-link:not(.openid-processed)", context) + .addClass('openid-processed') + .click( function() { $("#edit-pass-wrapper").hide(); $("#edit-name-wrapper").fadeOut('medium', function() { $("#edit-openid-url-wrapper").fadeIn('medium'); @@ -17,7 +20,9 @@ $(document).ready( $("a.user-link").show(); return false; }); - $("a.user-link").click( function() { + $("a.user-link:not(.openid-processed)", context) + .addClass('openid-processed') + .click(function() { $("#edit-openid-url-wrapper").hide(); $("#edit-pass-wrapper").show(); $("#edit-name-wrapper").show(); @@ -25,5 +30,5 @@ $(document).ready( $("a.openid-link").show(); return false; }); - }); +}; diff --git a/modules/system/system.js b/modules/system/system.js index 808dac7f5705526596aa6e8657a011db0a2aab36..3e0e3a501d2e942850a4520eeafc21f019568755 100644 --- a/modules/system/system.js +++ b/modules/system/system.js @@ -7,7 +7,13 @@ * This function is not used to verify whether or not clean URLs * are currently enabled. */ -Drupal.cleanURLsSettingsCheck = function() { +Drupal.behaviors.cleanURLsSettingsCheck = function(context) { + // This behavior attaches by ID, so is only valid once on a page. + // Also skip if we are on an install page, as Drupal.cleanURLsInstallCheck will handle + // the processing. + if ($("#clean-url.clean-url-processed, #clean-url.install").size()) { + return; + } var url = location.pathname +"admin/settings/clean-urls"; $("#clean-url .description span").html('<div id="testing">'+ Drupal.t('Testing clean URLs...') +"</div>"); $("#clean-url p").hide(); @@ -23,6 +29,7 @@ Drupal.cleanURLsSettingsCheck = function() { $("#clean-url .description span").append('<div class="warning">'+ Drupal.t('Your system configuration does not currently support this feature. The <a href="http://drupal.org/node/15365">handbook page on Clean URLs</a> has additional troubleshooting information.') +"</div>"); } }}); + $("#clean-url").addClass('clean-url-processed'); }; /** @@ -50,6 +57,7 @@ Drupal.cleanURLsInstallCheck = function() { $("#clean-url .description span").append('<div class="warning">'+ Drupal.settings.cleanURL.failure +"</div>"); } }}); + $("#clean-url").addClass('clean-url-processed'); }; Drupal.installDefaultTimezone = function() { @@ -60,14 +68,14 @@ Drupal.installDefaultTimezone = function() { /** * Show/hide custom format sections on the date-time settings page. */ -Drupal.dateTimeAutoAttach = function() { +Drupal.behaviors.dateTime = function(context) { // Show/hide custom format depending on the select's value. - $("select.date-format").change(function() { - $(this).parents("div.date-container").children("div.custom-container")[$(this).val() == "custom" ? "show" : "hide"](); + $('select.date-format:not(.date-time-processed)', context).change(function() { + $(this).addClass('date-time-processed').parents("div.date-container").children("div.custom-container")[$(this).val() == "custom" ? "show" : "hide"](); }); // Attach keyup handler to custom format inputs. - $("input.custom-format").keyup(function() { + $('input.custom-format:not(.date-time-processed)', context).addClass('date-time-processed').keyup(function() { var input = $(this); var url = Drupal.settings.dateTime.lookup +(Drupal.settings.dateTime.lookup.match(/\?q=/) ? "&format=" : "?format=") + Drupal.encodeURIComponent(input.val()); $.getJSON(url, function(data) { @@ -76,5 +84,5 @@ Drupal.dateTimeAutoAttach = function() { }); // Trigger the event handler to show the form input if necessary. - $("select.date-format").trigger("change"); -} + $('select.date-format', context).trigger('change'); +}; \ No newline at end of file diff --git a/modules/system/system.module b/modules/system/system.module index 5de9f028281fbed1f364ca163542453b59fbd11d..73f83cb13c1254824f6c3916915360fbe13b8933 100644 --- a/modules/system/system.module +++ b/modules/system/system.module @@ -616,13 +616,6 @@ function system_clean_url_settings() { if (!variable_get('clean_url', 0)) { if (strpos(request_uri(), '?q=') !== FALSE) { drupal_add_js(drupal_get_path('module', 'system') .'/system.js', 'module'); - drupal_add_js(' -// Global Killswitch -if (Drupal.jsEnabled) { - $(document).ready(function() { - Drupal.cleanURLsSettingsCheck(); - }); -}', 'inline'); $form['clean_url']['#description'] .= ' <span>'. t('Before enabling clean URLs, you must perform a test to determine if your server is properly configured. If you are able to see this page again after clicking the "Run the clean URL test" link, the test has succeeded and the radio buttons above will be available. If instead you are directed to a "Page not found" error, you will need to change the configuration of your server. The <a href="@handbook">handbook page on Clean URLs</a> has additional troubleshooting information.', array('@handbook' => 'http://drupal.org/node/15365')) .'</span>'; @@ -820,11 +813,7 @@ function system_rss_feeds_settings() { function system_date_time_settings() { drupal_add_js(drupal_get_path('module', 'system') .'/system.js', 'module'); drupal_add_js(array('dateTime' => array('lookup' => url('admin/settings/date-time/lookup'))), 'setting'); - drupal_add_js(' -// Global Killswitch -if (Drupal.jsEnabled) { - $(document).ready(Drupal.dateTimeAutoAttach); -}', 'inline'); + // Date settings: $zones = _system_zonelist(); diff --git a/modules/translation/translation.module b/modules/translation/translation.module index c7f464cd2b0de4d63ce56a7ba5b19a5a3fb8d22b..b45bf2126938b2ae32ad434c7f9a643a43064ca7 100644 --- a/modules/translation/translation.module +++ b/modules/translation/translation.module @@ -339,12 +339,12 @@ function translation_supported_type($type) { /** * Return paths of all translations of a node, based on - * its Drupal path. + * its Drupal path. * * @param $path * A Drupal path, for example node/432. * @return - * An array of paths of translations of the node accessible + * An array of paths of translations of the node accessible * to the current user keyed with language codes. */ function translation_path_get_translations($path) { diff --git a/modules/user/user.js b/modules/user/user.js index cbd46c992becc51589d2a71d9bbe9331b8b9d670..bdfa06b435867d00a00662d43f3132a2ac8dd0da 100644 --- a/modules/user/user.js +++ b/modules/user/user.js @@ -4,11 +4,10 @@ * Attach handlers to evaluate the strength of any password fields and to check * that its confirmation is correct. */ -Drupal.passwordAttach = function(context) { - var context = context || $(document); +Drupal.behaviors.password = function(context) { var translate = Drupal.settings.password; - $("input.password-field", context).each(function() { - var passwordInput = $(this); + $("input.password-field:not(.password-processed)", context).each(function() { + var passwordInput = $(this).addClass('password-processed'); var parent = $(this).parent(); // Wait this number of milliseconds before checking password. var monitorDelay = 700; @@ -173,11 +172,9 @@ Drupal.evaluatePasswordStrength = function(value) { * picture-related form elements depending on the current value of the * "Picture support" radio buttons. */ -if (Drupal.jsEnabled) { - $(document).ready(function () { - $('div.user-admin-picture-radios input[@type=radio]').click(function () { - $('div.user-admin-picture-settings')[['hide', 'show'][this.value]](); - }); - Drupal.passwordAttach(); +Drupal.behaviors.userSettings = function (context) { + $('div.user-admin-picture-radios input[@type=radio]:not(.userSettings-processed)', context).addClass('userSettings-processed').click(function () { + $('div.user-admin-picture-settings', context)[['hide', 'show'][this.value]](); }); -} +}; + diff --git a/profiles/default/default.profile b/profiles/default/default.profile index 7a2a6b14046d38b9e8333c449360ebfd4f163971..ac9f2ce256424e1bf6f50b4c153612093002408f 100644 --- a/profiles/default/default.profile +++ b/profiles/default/default.profile @@ -8,7 +8,7 @@ * An array of modules to be enabled. */ function default_profile_modules() { - return array('color', 'comment', 'help', 'taxonomy', 'dblog'); + return array('color', 'comment', 'help', 'taxonomy', 'dblog', 'update'); } /**