Bivio::UI::HTML::Widget::String
# Copyright (c) 1999-2007 bivio Software, Inc. All rights reserved.
# $Id$
package Bivio::UI::HTML::Widget::String;
use strict;
use Bivio::Base 'UI.Widget';
# C<Bivio::UI::HTML::Widget::String> draws a string with decoration. Does no
# alignment (see L<Bivio::UI::HTML::Widget::Grid|Bivio::UI::HTML::Widget::Grid>
# for layout issues).
#
# The string is html-escaped and newlines are converted to C<E<lt>brE<gt>>.
#
#
#
# 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<value> before escaping the html.
# Only valid if I<value> is not a widget.
#
# hard_newlines : boolean [1]
#
# Newlines force hard breaks in the text. Only valid if
# I<escape_html> is true.
#
# hard_spaces : boolean [0]
#
# Replace all spaces (not tabs or newlines) in the text with .
# Only valid if I<escape_html> 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<b_use('FacadeComponent.Font')|Bivio::UI::Font>.
#
# undef_value : string ['']
#
# What to display if I<value> is C<undef>.
# Not used if I<value> is a constant.
#
# value : array_ref (required)
#
# Dereferenced and passed to C<$source-E<gt>get_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<Bivio::UI::Widget::Join|Bivio::UI::Widget::Join>,
# 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.
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_blesser_of($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<String> widget with I<value> and I<font> (if supplied and defined).
# Pass C<0> (zero) as I<font> to set "no font". Will not set font, if C<undef>.
# Optionally, pass other I<attributes>.
#
#
# If I<attributes> 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_blesser_of($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_blesser_of($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;
}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_blesser_of($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;