# Copyright (c) 1999-2007 bivio Software, Inc. All rights reserved. # # Visit http://www.bivio.biz for more info. # # This library is free software; you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as # published by the Free Software Foundation; either version 2.1 of the # License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; If not, you may get a copy from: # http://www.opensource.org/licenses/lgpl-license.html # # $Id: String.pm,v 2.14 2010/10/17 22:19:25 nagler Exp $ package Bivio::UI::HTML::Widget::String; use strict; use Bivio::Base 'UI.Widget'; # C draws a string with decoration. Does no # alignment (see L # for layout issues). # # The string is html-escaped and newlines are converted to CbrE>. # # # # escape_html : boolean [see description] # # Should we escape HTML specials within the value? # # True by default for non-widgets. False by default if the value or the widget # value is a widget. # # format : Bivio::UI::HTML::Format [] # # format : string [] # # The name of the formatter to use on I before escaping the html. # Only valid if I is not a widget. # # hard_newlines : boolean [1] # # Newlines force hard breaks in the text. Only valid if # I is true. # # hard_spaces : boolean [0] # # Replace all spaces (not tabs or newlines) in the text with  . # Only valid if I is true. # # pad_left : int [0] # # Number of non-breaking spaces to pad on the left. # # pad_right : int [0] # # Number of non-breaking spaces to pad on the right. # # string_font : string [] (inherited, dynamic) # # The value to be passed to L. # # undef_value : string [''] # # What to display if I is C. # Not used if I is a constant. # # value : array_ref (required) # # Dereferenced and passed to C<$source-Eget_widget_value> # to get string to use (see below). The return value of # get_widget_value may be widget in which case render is called. # # value : string (required) # # Text to render. # # value : Bivio::UI::Widget (required) # # The widget to render. Typically, can only be # L, # but may be any widget. Purpose is to be able to set the # font on a collection of strings join. # # The values returned by the widget are not "escaped". The widget # must generate proper html. our($VERSION) = sprintf('%d.%02d', q$Revision: 2.14 $ =~ /\d+/g); my($_IDI) = __PACKAGE__->instance_data_index; my($_FORMAT) = b_use('UIHTML.Format'); my($_FONT) = b_use('FacadeComponent.Font'); my($_HTML) = b_use('Bivio.HTML'); my($_W) = b_use('UI.Widget'); sub NEW_ARGS { return [qw(value ?string_font)]; } sub initialize { my($self) = @_; my($fields) = $self->[$_IDI]; return if exists($fields->{value}); $fields->{font} = $self->ancestral_get('string_font', undef); # -1 is default true which is handled differently in widget and # html cases. $fields->{escape} = $self->get_or_default('escape_html', -1); $fields->{hard_newlines} = $self->get_or_default( 'hard_newlines', $fields->{escape}, ); $fields->{hard_spaces} = $self->get_or_default('hard_spaces', 0); my($pad_left) = $self->get_or_default('pad_left', 0); $fields->{prefix} = $pad_left > 0 ? (' ' x $pad_left) : ''; my($pad_right) = $self->get_or_default('pad_right', 0); $fields->{suffix} = $pad_right > 0 ? (' ' x $pad_right) : ''; my($f) = $self->unsafe_get('format', 0); $fields->{format} = $_FORMAT->get_instance($f) if $f; $fields->{undef_value} = $self->get_or_default('undef_value', ''); $fields->{value} = $self->get('value'); if ($fields->{is_literal} = !ref($fields->{value})) { # do nothing, formatter may be dynamic } elsif ($fields->{is_widget} = $_W->is_blessed($fields->{value})) { $fields->{value}->initialize_with_parent($self); } b_warn('is_widget and has formatter') if $fields->{is_widget} && $fields->{format}; return shift->SUPER::initialize(@_); } sub new { my($self) = shift->SUPER::new(@_); # Create a C widget with I and I (if supplied and defined). # Pass C<0> (zero) as I to set "no font". Will not set font, if C. # Optionally, pass other I. # # # If I supplied, creates with attribute (name, value) pairs. $self->[$_IDI] = {}; return $self; } sub render { my($self, $source, $buffer) = @_; my($fields) = $self->[$_IDI]; b_die("String widget not initialized: ", $self->get('value')) unless exists($fields->{value}); my($b) = ''; if ($fields->{is_literal}) { $b = _format($fields, $fields->{value}); } elsif ($fields->{is_widget}) { $fields->{value}->render($source, \$b); # Note the special treatment of non-default true. $b = _escape($fields, $b) if $fields->{escape} == 1; } else { my($v) = $self->unsafe_resolve_widget_value($fields->{value}, $source); $v = $self->unsafe_resolve_widget_value( $fields->{undef_value}, $source, ) unless defined($v); if (ref($v) && $_W->is_blessed($v)) { $self->initialize_value($v); $v->initialize_with_parent($self); $v->render($source, \$b); # Note the special treatment of non-default true. $b = _escape($fields, $b) if $fields->{escape} == 1; } else { $b .= _format($fields, $v); } } return unless length($b); my($f) = $fields->{font}; if (ref($f)) { $f = ''; $self->unsafe_render_value( 'string_font', $fields->{font}, $source, \$f); } my($p, $s) = $f ? $_FONT->format_html($f, $source->get_request) : ('', ''); $$buffer .= $p.$fields->{prefix}.$b.$fields->{suffix}.$s; return; } sub _escape { my($fields, $value) = @_; $value = $_HTML->escape($value); $value =~ s/ / /sg if $fields->{hard_spaces}; $value =~ s{\n}{
}mg if $fields->{hard_newlines}; $value =~ s/^\s+$/ /s; return $value; } sub _format { my($fields, $value) = @_; if ($fields->{format}) { $value = $fields->{format}->get_widget_value($value); return $value if $fields->{format}->result_is_html; } if (ref($value)) { b_die('got ref where scalar expected: ', $value) unless Bivio::UNIVERSAL->is_blessed($value) && $value->can('as_html'); return $value->as_html; } # Note the treatment of escape when -1 or +1. return $fields->{escape} ? _escape($fields, $value) : $value; } 1;