* Add enclair_db option to UserDB.pm. Allows logging of enclair password
[interchange.git] / code / Widget / htmlarea.widget
1 # Copyright 2005-2007 Interchange Development Group and others
2
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 2 of the License, or
6 # (at your option) any later version.  See the LICENSE file for details.
7
8 # $Id: htmlarea.widget,v 1.16 2007-09-26 19:56:56 racke Exp $
9
10 CodeDef htmlarea Widget 1
11 CodeDef htmlarea Description Rich text editor
12 CodeDef htmlarea Documentation <<EOD
13 =head1 NAME
14
15 HTMLArea widget for Interchange
16
17 =head1 SYNOPSIS
18
19   [display type=htmlarea name=foo height=NN width=NNN]
20
21  or
22
23   [table-editor
24         widget.foo=htmlarea
25         ...
26   ]
27
28 =head1 DESCRIPTION
29
30 The C<htmlarea> widget makes calls to a rich-text editor that replaces 
31 a C<TEXTAREA> component on supported browsers. It operates as a normal 
32 textarea otherwise.
33
34 Two flavours of rich-text editors are available, htmlarea (HTMLArea) and
35 fckeditor (FCKeditor).
36
37 Supported browsers include at least Mozilla 1.3.1 and higher, and
38 MSIE 6 and higher.
39
40 =head1 INSTALLATION
41
42 The flavour can be selected by the Interchange Variable HTMLAREA_FLAVOUR
43 or the flavour option and defaults to htmlarea.
44
45 To install the htmlarea flavour, get HTMLArea-3.0-RC1 or later and install 
46 in the C<htmlarea> directory of your DocumentRoot. 
47 That means that routines can be accessed with a base HREF of C</htmlarea/>).
48
49 To install the fckeditor flavour, get FCKeditor 2.1 or later and install 
50 in the C<fckeditor> directory of your DocumentRoot. 
51 That means that routines can be accessed with a base HREF of C</fckeditor/>.
52
53 Alternatively, you can set the Interchange Variable HTMLAREA_PATH to
54 the appropriate path.
55
56 This widget requires Interchange 5.0 and higher.
57
58 If you are planning on using it outside of the Interchange UI, you must
59 either have the output-style of layout (the "standard" demo) with a 
60 [scratch meta_header] call in the <HEAD> area, or you must place the
61 equivalent of the following in the header of any page to use this widget:
62
63     [tmp tmp_hpath][either]__HTMLAREA_PATH__[or]/htmlarea/[/either][/tmp]
64         <script type="text/javascript">
65            _editor_url = "[scratch tmp_hpath]";
66            _editor_lang = "en";
67         </script>
68         <script type="text/javascript" src="[scratch tmp_hpath]htmlarea.js"></script>
69
70 For the fckeditor flavour:
71
72     [tmp tmp_hpath][either]__HTMLAREA_PATH__[or]/htmlarea/[/either][/tmp]
73         <script type="text/javascript">
74            _editor_url = "[scratch tmp_hpath]";
75         </script>
76         <script type="text/javascript" src="[scratch tmp_hpath]fckeditor.js"></script>
77
78 Additionally for the fckeditor flavour, if "htmlarea_config" is set, upon
79 loading it will call a javascript function by the name of its value:
80
81     [display type=htmlarea name=foo height=NN width=NNN htmlarea_config="bar"]
82
83     <script>
84     function bar (fckobj) {
85         fckobj.ToolbarSet = 'Basic';
86     }
87     </script>
88
89 This is useful to pass fckeditor configurations, such as the above example "ToolbarSet".
90 Note that you must supply the Javascript function of (in this case) "bar" as shown, somewhere
91 on the same page for it to work. 
92
93 The "en" is the language locale to use. If you use the output-style
94 layout, this is automatically determined from the Interchange locale.
95 You can also override this with the Variable HTMLAREA_LANG. This is not
96 applicable for the fckeditor flavour.
97
98 =head1 BUGS
99
100 A bug in MSIE doesn't allow initialization of a textarea until the
101 complete document is loaded. This means that the editor toolbox will not
102 show up until the mouse enters the C<TEXTAREA>.
103
104 =cut
105 EOD
106
107 CodeDef htmlarea Routine <<EOR
108 sub {
109         my ($opt) = @_;
110 #::logDebug("called kupu widget, value=$opt->{value}");
111         use vars qw/$Tag/;
112
113         my %flavours = (htmlarea => {path => '/htmlarea/',
114                                         header => qq|
115 <script type="text/javascript">
116    _editor_url = "{PATH}";
117    _editor_lang = "{LANG}";
118 </script>
119 <script type="text/javascript" src="{PATH}htmlarea.js"></script>
120 |,
121                                         area => qq|<textarea id="htmlarea_{NAME}" rows="{HEIGHT}" cols={WIDTH} name="{NAME}"{ONMOUSE}>{VALUE}</textarea>|},
122                                         fckeditor => {path => '/fckeditor/',
123                                         header => qq|
124 <script type="text/javascript" src="{PATH}fckeditor.js"></script>
125 <script type="text/javascript">
126    _editor_url = "{PATH}";
127
128    function addLoadEvent(func) {
129         var oldonload = window.onload;
130         if (typeof window.onload != 'function') {
131                 window.onload = func;
132         } else {
133                 window.onload = function() {
134                 oldonload();
135                 func();
136                 }
137         }
138    }
139 </script>|,
140                                         pre => qq|<script>
141 addLoadEvent(function()
142 {
143     var {NAME}FCKeditor = new FCKeditor( '{NAME}', '{WIDTH}', '{HEIGHT}' ) ;
144     {NAME}FCKeditor.BasePath = _editor_url ;
145         {CONFIG?}{CONFIG}({NAME}FCKeditor);{/CONFIG?}
146     {NAME}FCKeditor.ReplaceTextarea() ;
147 });
148
149 </script>
150 |,
151                                         area => qq|<textarea id="{NAME}" rows="{HEIGHT}" cols="{WIDTH}" name="{NAME}">{VALUE}</textarea>|,
152                                         post => ''
153 });
154         
155         my $flavour = $opt->{flavour} || $::Variable->{HTMLAREA_FLAVOUR} || 'htmlarea';
156
157         my $fname = $opt->{form_name} || 'editor';
158
159         my $callpage = $opt->{append} || 'special/kupu';
160
161         my $pname = $opt->{name};
162
163         my $wname = $opt->{window_name} || "ic_kupu_$pname";
164
165         $pname =~ s/\W/_/g;
166
167         unless(defined $opt->{close_window}) {
168                 $opt->{close_window} = 1;
169         }
170
171         if(! $::Scratch->{htmlarea_added}) {
172                 $Tag->tmp({ name => 'htmlarea_added', body => 1 });
173                 $::Scratch->{meta_header} ||= '';
174                 my $path = $::Variable->{HTMLAREA_PATH} || $flavours{$flavour}->{path};
175                 my $lang = $::Variable->{HTMLAREA_LANG} || $::Scratch->{mv_locale} || 'en';
176                 $lang = substr($lang, 0, 2);
177                 $path =~ s:/*$:/:;
178                 $::Scratch->{meta_header} .= $Tag->uc_attr_list({hash => {path => $path, lang => $lang}}, $flavours{$flavour}->{header});
179         }
180
181         my $val;
182         if($opt->{value} =~ /</) {
183                 $val = HTML::Entities::encode($opt->{value});
184         }
185         else {
186                 $val = $opt->{value};
187         }
188         my $pre_scr = '';
189         my $post_scr = '';
190         my $onmouse = '';
191         my $htmlarea_config = '';
192         
193         if ($opt->{htmlarea_config}) {
194                 $htmlarea_config = ", $opt->{htmlarea_config}";
195         }
196
197         if($Session->{browser} =~ /MSIE/) {
198                 if ($flavour eq 'htmlarea') {
199                     $pre_scr = qq{
200 <script>
201 var htmlarea_needinit_$pname = true;
202 </script>
203 };
204                         $onmouse = qq{ onMouseOver="if(htmlarea_needinit_$pname) { HTMLArea.replace('htmlarea_$pname'$htmlarea_config); htmlarea_needinit_$pname=false }"};
205                 }
206         }
207         else {
208                 if ($flavour eq 'fckeditor') {
209                         $post_scr = <<EOF;
210
211 EOF
212                 } else {
213                         $post_scr = <<EOF;
214 <script>
215         HTMLArea.replace('htmlarea_$pname'$htmlarea_config);
216 </script>
217 EOF
218                 }
219         }
220
221     $opt->{height} =~ s/\D+//;
222     $opt->{width} =~ s/\D+//;
223
224         $pre_scr .= $Tag->uc_attr_list({hash => {name => $pname, width => $opt->{width}, height => $opt->{height},
225                                                                                                                                         config => $flavour eq 'fckeditor' ? $opt->{htmlarea_config} : undef },
226                                                                         body => $flavours{$flavour}->{pre}});
227         
228         $opt->{anchor_style} ||= 'font-size: smaller';
229
230         my $extra = $opt->{anchor_class} ? qq{ class="$opt->{anchor_class}"} : '';
231         $extra .= qq{ style="$opt->{anchor_style}"} if $opt->{anchor_style};
232         my $textra = $opt->{text_class} ? qq{ class="$opt->{text_class}"} : '';
233         $textra .= qq{ style="$opt->{text_style}"} if $opt->{text_style};
234
235         my $wid = $pre_scr . $Tag->uc_attr_list({hash => {name => $pname,
236                 height => $opt->{height}, width => $opt->{width}, onmouse => $onmouse,
237                 value => $val}, body => $flavours{$flavour}->{area}}) . $post_scr;
238         
239         return $wid;
240 }
241 EOR