Index: misc/collapse.js =================================================================== RCS file: /cvs/drupal/drupal/misc/collapse.js,v retrieving revision 1.10 diff -u -F^f -r1.10 collapse.js --- misc/collapse.js 11 Jan 2007 03:38:31 -0000 1.10 +++ misc/collapse.js 21 Jan 2007 05:49:33 -0000 @@ -11,12 +11,12 @@ complete: function() { // Make sure we open to height auto $(this).css('height', 'auto'); - Drupal.collapseScrollIntoView(this.parentNode); + Drupal.scrollIntoView(this.parentNode); this.parentNode.animating = false; }, step: function() { // Scroll the fieldset into view - Drupal.collapseScrollIntoView(this.parentNode); + Drupal.scrollIntoView(this.parentNode); } }); if (typeof Drupal.textareaAttach != 'undefined') { @@ -32,23 +32,6 @@ } } -/** - * Scroll a given fieldset into view as much as possible. - */ -Drupal.collapseScrollIntoView = function (node) { - var h = self.innerHeight || document.documentElement.clientHeight || $('body')[0].clientHeight || 0; - var offset = self.pageYOffset || document.documentElement.scrollTop || $('body')[0].scrollTop || 0; - var pos = Drupal.absolutePosition(node); - var fudge = 55; - if (pos.y + node.offsetHeight + fudge > h + offset) { - if (node.offsetHeight > h) { - window.scrollTo(0, pos.y); - } else { - window.scrollTo(0, pos.y + node.offsetHeight - h + fudge); - } - } -} - // Global Killswitch if (Drupal.jsEnabled) { $(document).ready(function() { Index: misc/drupal.js =================================================================== RCS file: /cvs/drupal/drupal/misc/drupal.js,v retrieving revision 1.29 diff -u -F^f -r1.29 drupal.js --- misc/drupal.js 14 Oct 2006 02:39:48 -0000 1.29 +++ misc/drupal.js 21 Jan 2007 05:49:33 -0000 @@ -200,6 +200,39 @@ return uri.indexOf('?q=') ? item : item.replace('%26', '%2526').replace('%23', '%2523'); }; +/** + * Equivalent of check_plain(). + */ +Drupal.checkPlain = function (text) { + var entities = { + '&':'&', + '<':'<', + '>':'>', + '"':'"' + }; + for (i in entities) { + text = text.replace(new RegExp(i, 'g'), entities[i]); + } + return text; +} + +/** + * Scroll a given element into view as much as possible. + */ +Drupal.scrollIntoView = function (node) { + var h = self.innerHeight || document.documentElement.clientHeight || $('body')[0].clientHeight || 0; + var offset = self.pageYOffset || document.documentElement.scrollTop || $('body')[0].scrollTop || 0; + var pos = Drupal.absolutePosition(node); + var fudge = 55; + if (pos.y + node.offsetHeight + fudge > h + offset) { + if (node.offsetHeight > h) { + window.scrollTo(0, pos.y - 20); + } else { + window.scrollTo(0, pos.y - 20 + node.offsetHeight - h + fudge); + } + } +} + // Global Killswitch on the element if (Drupal.jsEnabled) { document.documentElement.className = 'js'; Index: misc/textarea.js =================================================================== RCS file: /cvs/drupal/drupal/misc/textarea.js,v retrieving revision 1.11 diff -u -F^f -r1.11 textarea.js --- misc/textarea.js 7 Sep 2006 08:05:31 -0000 1.11 +++ misc/textarea.js 21 Jan 2007 05:49:33 -0000 @@ -1,15 +1,25 @@ // $Id: textarea.js,v 1.11 2006/09/07 08:05:31 dries Exp $ +// Auto-expand based on "Interface Elements for jQuery" by Stefan Petre. + Drupal.textareaAttach = function() { + var i = 0; + // Attach to all unprocessed textareas. $('textarea.resizable:not(.processed)').each(function() { var textarea = $(this).addClass('processed'), staticOffset = null; + // We use a helper div to measure text. We wrap it an overflow: hidden + // container to avoid lengthening the page scrollbar. + $('body').append('
'); + var helper = $('#expanderHelper'+ i); + + // Wrap textarea and add grippie. $(this).wrap('') .parent().append($('').mousedown(startDrag)); - var grippie = $('div.grippie', $(this).parent())[0]; grippie.style.marginRight = (grippie.offsetWidth - $(this)[0].offsetWidth) +'px'; + // Clicking down on the grippie function startDrag(e) { staticOffset = textarea.height() - Drupal.mousePosition(e).y; textarea.css('opacity', 0.25); @@ -17,15 +27,87 @@ return false; } + // Moving the mouse during a drag. function performDrag(e) { textarea.height(Math.max(32, staticOffset + Drupal.mousePosition(e).y) + 'px'); return false; } + // Letting go of the button during drag. function endDrag(e) { $(document).unmousemove(performDrag).unmouseup(endDrag); textarea.css('opacity', 1); } + + // Get text styles and apply them to the helper. + var style = { + fontFamily: $(this).css('fontFamily')||'', + fontSize: $(this).css('fontSize')||'', + fontWeight: $(this).css('fontWeight')||'', + fontStyle: $(this).css('fontStyle')||'', + fontStretch: $(this).css('fontStretch')||'', + fontVariant: $(this).css('fontVariant')||'', + letterSpacing: $(this).css('letterSpacing')||'', + wordSpacing: $(this).css('wordSpacing')||'', + lineHeight: $(this).css('lineHeight')||'', + textWrap: 'unrestricted' + }; + helper.css(style); + + // Measure the text and some extra padding. + helper.html('DruP'); + var spacer = helper[0].offsetWidth; + + // Add auto-expand event handler and fire it once. + $(this).blur(expand).keyup(expand).keypress(expand); + var last = this.value; + expand.apply(this); + + var time = (new Date()).getTime(); + + // Auto-expand a textarea. + function expand() { + var e = this; + + // Don't expand more than once every 250ms. + var now = (new Date()).getTime(); + if (now - time < 250) { + return; + } + time = now; + + // Force a tiny delay to ensure we get the entire value including the + // change this event causes. + window.setTimeout(function () { + // Get contents + if (!e.value || last == e.value) { + return; + } + var text = (last = e.value); + + // Don't expand for extremely large textareas where we are sure to be + // at full size already. + if (e.value.length > 10000) { + return; + } + + // Convert text to HTML and size it. + var html = Drupal.checkPlain(text); + html = html.replace(new RegExp("\\n", "g"), "