diff --git a/docs/changelog/6.x.x.txt b/docs/changelog/6.x.x.txt index 4cd79203e..9d2f33078 100644 --- a/docs/changelog/6.x.x.txt +++ b/docs/changelog/6.x.x.txt @@ -102,6 +102,7 @@ - added [ 881817 ] allowed characters in username - added [ 1231386 ] Insert WebGUI Image - added [ 1205807 ] ability to report file size in File template + - added [ 1201811 ] resizable textAreas - added [ 1376374 ] WebGUI should return a Last-Modified http/1.x header - fix [ 1178981 ] IE is in "quirks mode" - multi-column layout templates break diff --git a/docs/upgrades/upgrade_6.8.8-6.99.0.pl b/docs/upgrades/upgrade_6.8.8-6.99.0.pl index db901272e..6725143b6 100644 --- a/docs/upgrades/upgrade_6.8.8-6.99.0.pl +++ b/docs/upgrades/upgrade_6.8.8-6.99.0.pl @@ -51,9 +51,17 @@ addRichEditUpload(); updateArticle(); updateScratch(); installSQLForm(); +addResizableTextareas(); finish($session); # this line required +#------------------------------------------------- +sub addResizableTextareas { + print "\tAllowing user to resize text areas on the fly.\n"; + $session->setting->remove("textAreaCols"); + $session->setting->remove("textAreaRows"); +} + #------------------------------------------------- sub updateScratch { print "\tIncreasing size of scratch variables.\n"; diff --git a/lib/WebGUI/Asset/RichEdit.pm b/lib/WebGUI/Asset/RichEdit.pm index 5eae8face..fb3c058cd 100644 --- a/lib/WebGUI/Asset/RichEdit.pm +++ b/lib/WebGUI/Asset/RichEdit.pm @@ -443,6 +443,7 @@ sub getRichEditor { auto_reset_designmode => "true", cleanup_callback => "tinyMCE_WebGUI_Cleanup", urlconvertor_callback => "tinyMCE_WebGUI_URLConvertor", + theme_advanced_resizing => "true", theme_advanced_buttons1 => join(",",@toolbarRow1), theme_advanced_buttons2 => join(",",@toolbarRow2), theme_advanced_buttons3 => join(",",@toolbarRow3), @@ -454,6 +455,7 @@ sub getRichEditor { nowrap => $self->getValue("nowrap") ? "true" : "false", directionality => $self->getValue("directionality"), theme_advanced_toolbar_location => $self->getValue("toolbarLocation"), + theme_advanced_statusbar_location => "bottom", valid_elements => $self->getValue("validElements"), ); foreach my $button (@toolbarButtons) { diff --git a/lib/WebGUI/Form/Codearea.pm b/lib/WebGUI/Form/Codearea.pm index f7e22ce46..7e9bc18f7 100644 --- a/lib/WebGUI/Form/Codearea.pm +++ b/lib/WebGUI/Form/Codearea.pm @@ -45,6 +45,18 @@ See the super class for additional details. =head3 additionalTerms +=head4 width + +The width of this control in pixels. Defaults to 550 pixels. + +=head4 height + +The height of this control in pixels. Defaults to 450 pixels. + +=head4 style + +Style attributes besides width and height which should be specified using the above parameters. Be sure to escape quotes if you use any. + The following additional parameters have been added via this sub class. =head4 profileEnabled @@ -62,6 +74,15 @@ sub definition { formName=>{ defaultValue=>$i18n->get("codearea") }, + height=>{ + defaultValue=> 450 + }, + width=>{ + defaultValue=> 550 + }, + style=>{ + defaultValue => undef, + }, profileEnabled=>{ defaultValue=>1 } @@ -80,7 +101,7 @@ Renders a code area field. sub toHtml { my $self = shift; $self->session->style->setScript($self->session->config->get("extrasURL").'/TabFix.js',{type=>"text/javascript"}); - $self->set("extras", $self->get('extras') . ' style="width: 600px; height: 400px" onkeypress="return TabFix_keyPress(event)" onkeydown="return TabFix_keyDown(event)"'); + $self->set("extras", $self->get('extras').' onkeypress="return TabFix_keyPress(event)" onkeydown="return TabFix_keyDown(event)"'); return $self->SUPER::toHtml; } diff --git a/lib/WebGUI/Form/File.pm b/lib/WebGUI/Form/File.pm index 8e84c2201..8d4214120 100644 --- a/lib/WebGUI/Form/File.pm +++ b/lib/WebGUI/Form/File.pm @@ -213,7 +213,7 @@ sub toHtml { foreach my $file (@{$storage->getFiles}) { if ($self->get("deleteFileUrl")) { $uploadControl .= '

' - .'x

'; + .'x

'; } $uploadControl .= '

' .''
diff --git a/lib/WebGUI/Form/HTMLArea.pm b/lib/WebGUI/Form/HTMLArea.pm
index df03a18ea..b860cebe4 100644
--- a/lib/WebGUI/Form/HTMLArea.pm
+++ b/lib/WebGUI/Form/HTMLArea.pm
@@ -49,13 +49,17 @@ See the super class for additional details.
 
 The following additional parameters have been added via this sub class.
 
-=head4 rows
+=head4 width
 
-The number of rows (in characters) tall the box should be. Defaults to the setting textAreaRows + 20.
+The width of this control in pixels. Defaults to 500 pixels.
 
-=head4 columns
+=head4 height
 
-The number of columns (in characters) wide the box should be. Defaults to the setting textAreaCols + 10.
+The height of this control in pixels.  Defaults to 400 pixels.
+
+=head4 style
+
+Style attributes besides width and height which should be specified using the above parameters. Be sure to escape quotes if you use any.
 
 =head4 richEditId
 
@@ -76,12 +80,15 @@ sub definition {
                 formName=>{
                         defaultValue=>$i18n->get({ - defaultValue=> $session->setting->get("textAreaRows")+20 - }, - columns=>{ - defaultValue=> $session->setting->get("textAreaCols")+10 - }, + height=>{ + defaultValue=> 400 + }, + width=>{ + defaultValue=> 500 + }, + style=>{ + defaultValue => undef, + }, richEditId=>{ defaultValue=>$session->setting->get("richEditor") || "PBrichedit000000000001" }, @@ -118,6 +125,7 @@ sub toHtml { my $self = shift; $self->session->style->setScript($self->session->config->get("extrasURL").'/textFix.js',{ type=>'text/javascript' }); $self->set("extras", $self->get('extras') . ' onblur="fixChars(this.form.'.$self->get("name").')" mce_editable="true" '); + $self->set("resizeable", 0); return $self->SUPER::toHtml.WebGUI::Asset::RichEdit->new($self->session,$self->get("richEditId"))->getRichEditor($self->get('id')); my $i18n = WebGUI::International->new($self->session); my $richEdit = WebGUI::Asset::RichEdit->new($self->session,$self->get("richEditId")); diff --git a/lib/WebGUI/Form/Image.pm b/lib/WebGUI/Form/Image.pm index df6d292d2..c96f98888 100644 --- a/lib/WebGUI/Form/Image.pm +++ b/lib/WebGUI/Form/Image.pm @@ -186,7 +186,7 @@ sub toHtml { foreach my $file (@{$storage->getFiles}) { if ($self->get("deleteFileUrl")) { $uploadControl .= '

' - .'x

'; + .'x

'; } my $image = $storage->isImage($file) ? $storage->getThumbnailUrl($file) : $storage->getFileIconUrl($file); $uploadControl .= '

' diff --git a/lib/WebGUI/Form/Textarea.pm b/lib/WebGUI/Form/Textarea.pm index 7b197e543..c7137cc48 100644 --- a/lib/WebGUI/Form/Textarea.pm +++ b/lib/WebGUI/Form/Textarea.pm @@ -46,18 +46,26 @@ See the super class for additional details. The following additional parameters have been added via this sub class. -=head4 rows +=head4 width -The number of rows (in characters) tall the box should be. Defaults to the setting textAreaRows or 5 if that's not specified. +The width of this control in pixels. Defaults to 400 pixels. -=head4 columns +=head4 height -The number of columns (in characters) wide the box should be. Defaults to the setting textAreaCols or 50 if that's not specified. +The height of this control in pixels. Defaults to 150 pixels. + +=head4 style + +Style attributes besides width and height which should be specified using the above parameters. Be sure to escape quotes if you use any. =head4 profileEnabled Flag that tells the User Profile system that this is a valid form element in a User Profile +=head4 resizeable + +A boolean indicating whether the text area can be reized by users. Defaults to 1. + =cut sub definition { @@ -69,11 +77,17 @@ sub definition { formName=>{ defaultValue=>$i18n->get("476") }, - rows=>{ - defaultValue=> $session->setting->get("textAreaRows") || 5 + height=>{ + defaultValue=> 150 }, - columns=>{ - defaultValue=> $session->setting->get("textAreaCols") || 50 + width=>{ + defaultValue=> 400 + }, + style=>{ + defaultValue => undef, + }, + resizeable => { + defaultValue => 1, }, profileEnabled=>{ defaultValue=>1 @@ -92,8 +106,15 @@ Renders an input tag of type text. sub toHtml { my $self = shift; + my $resize = undef; + if ($self->get("resizeable")) { + my $i18n = WebGUI::International->new($self->session, "Form_Textarea"); + $self->session->style->setScript($self->session->config->get("extrasURL")."/resizeable_textarea.js", {type=>"text/javascript"}); + $resize = ''.$i18n->get('; + } my $value = $self->fixMacros($self->fixTags($self->fixSpecialCharacters($self->get("value")))); - return ''; + my $style = "width: ".$self->get('width')."px; height: ".$self->get('height')."px; ".$self->get("style"); + return ''.$resize; } diff --git a/lib/WebGUI/Operation/Settings.pm b/lib/WebGUI/Operation/Settings.pm index 25314ad94..368429e8b 100644 --- a/lib/WebGUI/Operation/Settings.pm +++ b/lib/WebGUI/Operation/Settings.pm @@ -135,18 +135,6 @@ sub www_editSettings { -options=>WebGUI::Asset::RichEdit->getList($session), -defaultValue=>["PBrichedit000000000001"] ); - $tabform->getTab("ui")->integer( - -name=>"textAreaRows", - -label=>$i18n->get(463), - -hoverHelp=>$i18n->get('463 description'), - -value=>$session->setting->get("textAreaRows") - ); - $tabform->getTab("ui")->integer( - -name=>"textAreaCols", - -label=>$i18n->get(464), - -hoverHelp=>$i18n->get('464 description'), - -value=>$session->setting->get("textAreaCols") - ); $tabform->getTab("ui")->integer( -name=>"textBoxSize", -label=>$i18n->get(465), diff --git a/lib/WebGUI/Session/Icon.pm b/lib/WebGUI/Session/Icon.pm index e883c2eab..f7477ec9e 100644 --- a/lib/WebGUI/Session/Icon.pm +++ b/lib/WebGUI/Session/Icon.pm @@ -54,13 +54,13 @@ These subroutines are available from this package: #------------------------------------------------------------------- -=head2 _getBaseURL ( ) +=head2 getBaseURL ( ) Returns the base URL for this user's toolbar icon set. =cut -sub _getBaseURL { +sub getBaseURL { my $self = shift; my $url = $self->session->config->get("extrasURL").'/toolbar/'; if ($self->session->user->profileField("toolbar") ne "useLanguageDefault") { @@ -95,7 +95,7 @@ sub copy { my $pageURL = shift || $self->session->url->getRequestedUrl; my $i18n = WebGUI::International->new($self->session,'Icon'); my $output = '

'; - $output .= ''.$i18n->get('Copy').'

'; + $output .= ''.$i18n->get('Copy').'

'; return $output; } @@ -121,7 +121,7 @@ sub cut { my $pageURL = shift || $self->session->url->getRequestedUrl; my $i18n = WebGUI::International->new($self->session,'Icon'); my $output = '

'; - $output .= ''.$i18n->get('Cut').'

'; + $output .= ''.$i18n->get('Cut').'

'; return $output; } @@ -169,7 +169,7 @@ sub delete { } my $i18n = WebGUI::International->new($self->session,'Icon'); my $output = '

'; - $output .= ''.$i18n->get('Delete').'

'; + $output .= ''.$i18n->get('Delete').'

'; return $output; } @@ -184,7 +184,7 @@ Generates an icon that can be used to drag content. sub drag { my $self = shift; my $i18n = WebGUI::International->new($self->session,'Icon'); - return '

'.$i18n->get('Drag').'

'; + return '

'.$i18n->get('Drag').'

'; } #------------------------------------------------------------------- @@ -209,7 +209,7 @@ sub edit { my $pageURL = shift || $self->session->url->getRequestedUrl; my $i18n = WebGUI::International->new($self->session,'Icon'); my $output = '

'; - $output .= ''.$i18n->get('Edit').'

'; + $output .= ''.$i18n->get('Edit').'

'; return $output; } @@ -235,7 +235,7 @@ sub export { my $pageURL = shift || $self->session->url->getRequestedUrl; my $i18n = WebGUI::International->new($self->session,'Icon'); my $output = '

'; - $output .= ''.$i18n->get('Export').'

'; + $output .= ''.$i18n->get('Export').'

'; return $output; } @@ -286,7 +286,7 @@ sub locked { my $pageURL = shift || $self->session->url->getRequestedUrl; my $i18n = WebGUI::International->new($self->session,'Icon'); my $output = '

'; - $output .= ''.$i18n->get('locked').'

'; + $output .= ''.$i18n->get('locked').'

'; return $output; } @@ -312,7 +312,7 @@ sub manage { my $pageURL = shift || $self->session->url->getRequestedUrl; my $i18n = WebGUI::International->new($self->session,'Icon'); my $output = '

'; - $output .= ''.$i18n->get('Manage').'

'; + $output .= ''.$i18n->get('Manage').'

'; return $output; } @@ -338,7 +338,7 @@ sub moveBottom { my $pageURL = shift || $self->session->url->getRequestedUrl; my $i18n = WebGUI::International->new($self->session,'Icon'); my $output = '

'; - $output .= ''.$i18n->get('Move To Bottom').'

'; + $output .= ''.$i18n->get('Move To Bottom').'

'; return $output; } @@ -366,7 +366,7 @@ sub moveDown { my $i18n = WebGUI::International->new($self->session,'Icon'); my $output = '

'; $output .= '' unless $disabled; - $output .= ''.$i18n->get('Move Down').''; + $output .= ''.$i18n->get('Move Down').''; $output .= '' unless $disabled; $output .= '

'; return $output; @@ -394,7 +394,7 @@ sub moveLeft { my $pageURL = shift || $self->session->url->getRequestedUrl; my $i18n = WebGUI::International->new($self->session,'Icon'); my $output = '

'; - $output .= ''.$i18n->get('Move Left').'

'; + $output .= ''.$i18n->get('Move Left').'

'; return $output; } @@ -420,7 +420,7 @@ sub moveRight { my $pageURL = shift || $self->session->url->getRequestedUrl; my $i18n = WebGUI::International->new($self->session,'Icon'); my $output = '

'; - $output .= ''.$i18n->get('Move Right').'

'; + $output .= ''.$i18n->get('Move Right').'

'; return $output; } @@ -446,7 +446,7 @@ sub moveTop { my $pageURL = shift || $self->session->url->getRequestedUrl; my $i18n = WebGUI::International->new($self->session,'Icon'); my $output = '

'; - $output .= ''.$i18n->get('Move To Top').'

'; + $output .= ''.$i18n->get('Move To Top').'

'; return $output; } @@ -474,7 +474,7 @@ sub moveUp { my $i18n = WebGUI::International->new($self->session,'Icon'); my $output = '

'; $output .= '' unless $disabled; - $output .= ''.$i18n->get('Move Up').''; + $output .= ''.$i18n->get('Move Up').''; $output .= '' unless $disabled; $output .= '

'; return $output; @@ -536,7 +536,7 @@ sub shortcut { my $pageURL = shift || $self->session->url->getRequestedUrl; my $i18n = WebGUI::International->new($self->session,'Icon'); my $output = '

'; - $output .= ''.$i18n->get('Create Shortcut').'

'; + $output .= ''.$i18n->get('Create Shortcut').'

'; return $output; } @@ -562,7 +562,7 @@ sub view { my $pageURL = shift || $self->session->url->getRequestedUrl; my $i18n = WebGUI::International->new($self->session,'Icon'); my $output = '

'; - $output .= ''.$i18n->get('View').'

'; + $output .= ''.$i18n->get('View').'

'; return $output; } diff --git a/lib/WebGUI/i18n/English/Form_Textarea.pm b/lib/WebGUI/i18n/English/Form_Textarea.pm new file mode 100644 index 000000000..a3050e644 --- /dev/null +++ b/lib/WebGUI/i18n/English/Form_Textarea.pm @@ -0,0 +1,12 @@ +package WebGUI::i18n::English::Form_Textarea; ##Be sure to change the package name to match the filename + +our $I18N = { ##hashref of hashes + 'drag to resize' => { + message => q|Drag to Resize|, + lastUpdated => 0, + context => q|alt tag for the text area drag icon| + }, + +}; + +1; diff --git a/lib/WebGUI/i18n/English/WebGUI.pm b/lib/WebGUI/i18n/English/WebGUI.pm index 3365ad02c..f381d38c1 100644 --- a/lib/WebGUI/i18n/English/WebGUI.pm +++ b/lib/WebGUI/i18n/English/WebGUI.pm @@ -137,11 +137,6 @@ our $I18N = { context => q|Title of the statistics viewer for the admin console.| }, - '463' => { - message => q|Text Area Rows|, - lastUpdated => 1031514049 - }, - '451' => { message => q|is required.|, lastUpdated => 1031514049 @@ -2557,11 +2552,6 @@ The headings of columns on things like message boards and user contributions. lastUpdated => 1078243385 }, - '464' => { - message => q|Text Area Columns|, - lastUpdated => 1031514049 - }, - '363' => { message => q|Page Template Position|, lastUpdated => 1034736999 @@ -3525,16 +3515,6 @@ and tracked by WebGUI.|, lastUpdated => 1120239343, }, - '463 description' => { - message => q|How many rows of characters will be displayed in textareas on the site.|, - lastUpdated => 1120239343, - }, - - '464 description' => { - message => q|How many columns of characters will be displayed in textareas on the site. |, - lastUpdated => 1120239343, - }, - '465 description' => { message => q|How many characters can be displayed at once in text boxes on the site. |, lastUpdated => 1120239343, diff --git a/www/extras/resizeable_textarea.js b/www/extras/resizeable_textarea.js new file mode 100644 index 000000000..c956b1ae3 --- /dev/null +++ b/www/extras/resizeable_textarea.js @@ -0,0 +1,165 @@ +/* -*-mode: Java; coding: latin-1;-*- Time-stamp: "2005-05-13 20:47:10 ADT" + + "Resizeable textarea functions" by Sean M. Burke, sburke@cpan.org, 2005 + + You can use, modify, and redistribute this only under the terms of the + Perl Artistic License: + http://www.perl.com/pub/a/language/misc/Artistic.html + +*/ + +var // Configurables: + tar_Drag_increments = 15, // number of pixels that we grow by + + // Sizes (in pixels) that no draggable textarea should exceed: + tar_Min_Height = 120, tar_Min_Width = 120, + tar_Max_Height = 1400, tar_Max_Width = 1400 +; + +// End of configurables + +//========================================================================== +var tar_Textarea, tar_Orig_width, tar_Orig_height, tar_Grip, tar_Cursor_start_x, tar_Cursor_start_y; + +function tar_drag_start (event, textarea_id) { + Textarea = tar_id(textarea_id); + + if(! tar_find_draggable(event) ) return; + + tar_add_class(Grip, "activedrag"); + + Cursor_start_x = event.clientX; + Cursor_start_y = event.clientY; + Orig_width = parseInt( Textarea.style.width , 10 ); + Orig_height = parseInt( Textarea.style.height , 10 ); + + // Capture mousemove and mouseup events on the page. + document.addEventListener("mousemove", tar_drag_move, true); + document.addEventListener("mouseup", tar_drag_stop, true); + + event.preventDefault(); + return; +} + +// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + +function tar_drag_move(event) { + var + new_width = event.clientX - Cursor_start_x + Orig_width , + new_height = event.clientY - Cursor_start_y + Orig_height; + + new_width = tar_constrain_range(tar_Min_Width ,new_width , tar_Max_Width, tar_Drag_increments);; + new_height = tar_constrain_range(tar_Min_Height,new_height, tar_Max_Height, tar_Drag_increments);; + + Textarea.style.width = new_width+'px'; + Textarea.style.height = new_height+'px'; + + event.preventDefault(); + return; +} + +// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + +function tar_drag_stop(event) { + // Stop capturing the mousemove and mouseup events. + tar_remove_class(Grip, "activedrag"); + document.removeEventListener("mousemove", tar_drag_move, true); + document.removeEventListener("mouseup", tar_drag_stop, true); + return; +} + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +function tar_constrain_range (min, i, max, incr) { + if(incr) i = Math.floor(i/incr) * incr; + return( + (i > max) ? max + :(i < min) ? min + : i + ); +} + +// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + +function tar_find_draggable (event) { + if(!event) throw tar_complaining("No event?!"); + + var el = event.target; + if(!el) { + if(window.event) throw tar_complaining( +"Your browser is too old to allow textarea resizing. Upgrade at getfirefox.com" + ); + // Modern browsers implement the DOM Events model, dammit! + + throw tar_complaining("No event target?!"); + } + + //trace("Dragging ", el.tagName, "#", el.id); + + if (el.nodeType == document.TEXT_NODE) el = el.parentNode; + while(el) { + if( el.tagName == "BODY" ) { el = false; break; } + if( tar_has_class(el, 'draggable') ) break; // found it! + el = el.parentNode; + } + if(!el) return false; // undraggable + Grip = el; + return true; +} + + +// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . +// Misc library functions: + +function tar_has_class (el, classname) { + return( + (" " + (el.className || '') + " ").indexOf(classname) >= 0 + ); +} + +function tar_add_class (el, newclass) { + var classes = (el.className || '').split(" "); + classes.push(newclass); + el.className = classes.join(" "); + return el; +} + +function tar_remove_class (el, endclass) { + if(!el.className) return el; + var classes = el.className.split(" "); + for(var i = 0; i < classes.length; i++) { + if(classes[i] == endclass) classes[i] = ''; + } + el.className = classes.join(" "); + return el; +} + +function tar_id (name) { // find element with the given ID, else exception. + var object = tar_id_try(name); + if( ! object ) throw tar_complaining("Failed to find element with id='" + + name + "' in " + document.location ); + return object; +} + +function tar_id_try (name) { + var object = document.getElementById(name); + return object; +} + +function tar_complaining () { + var _ = []; + for(var i = 0; i < arguments.length; i++) { _.push(arguments[i]) } + _ = _.join(""); + if(! _.length) out = "Unknown error!?!"; + void alert(_); + return new Error(_,_); +} + +// And a sanity-check: +if(!document.getElementById) throw tar_complaining( +"Your browser is too old to show this page quite right. Upgrade at getfirefox.com" +); + + +//End +