fix image text
[pear] / HTML / Javascript.php
1 <?php
2 /* vim: set expandtab tabstop=4 shiftwidth=4: */
3 // +----------------------------------------------------------------------+
4 // | PHP Version 4                                                        |
5 // +----------------------------------------------------------------------+
6 // | Copyright (c) 1997-2003 The PHP Group                                |
7 // +----------------------------------------------------------------------+
8 // | This source file is subject to version 3.0 of the PHP license,       |
9 // | that is bundled with this package in the file LICENSE, and is        |
10 // | available at through the world-wide-web at                           |
11 // | http://www.php.net/license/3_0.txt.                                  |
12 // | If you did not receive a copy of the PHP license and are unable to   |
13 // | obtain it through the world-wide-web, please send a note to          |
14 // | license@php.net so we can mail you a copy immediately.               |
15 // +----------------------------------------------------------------------+
16 // | Authors: Tal Peer <tal@php.net>                                      |
17 // |          Pierre-Alain Joye <paj@pearfr.org>                          |
18 // +----------------------------------------------------------------------+
19 // $Id: Javascript.php 193835 2005-08-18 08:55:07Z alan_k $
20
21 /**
22  * A class for performing basic JavaScript operations
23  *
24  * Usage example:
25  * <code>
26  * echo "<html><head><title>JS Test</title></head><body>";
27  * $js = new HTML_Javascript();
28  * echo $js->startScript();
29  * echo $js->writeLine('foo',false);
30  * echo $js->writeLine('bar[0]', true);
31  * echo $js->writeLine('bar[3]', true);
32  * echo $js->endScript();
33  * echo "</body></html>";
34  * </code>
35  * TODO:
36  * - Error handler
37  * - Validation mechanism
38  * - Rollovers
39  * - Importation from external files
40  * - Themed popups
41  *
42  * @author  Tal Peer <tal@php.net>
43  * @author  Pierre-Alain Joye <paj@pearfr.org>
44  * @version 1.1.3
45  * @package HTML_Javascript
46  * @example examples/javascript.php Usage of HTML_Javascript
47  * @licence http://www.php.net/license/3_0.txt PHP Licence 3.0
48  * @access  public
49  */
50
51 //Error codes
52
53 /**
54  * No script started error
55  */
56 define('HTML_JAVASCRIPT_ERROR_NOSTART', 500, true);
57
58 /**
59  * Unknown error
60  */
61 define('HTML_JAVASCRIPT_ERROR_UNKNOWN', 599, true);
62
63 /**
64  * Last script was not ended error
65  */
66 define('HTML_JAVASCRIPT_ERROR_NOEND', 501, true);
67
68 /**
69  * No file was specified for setOutputMode()
70  */
71 define('HTML_JAVASCRIPT_ERROR_NOFILE', 505, true);
72
73 /**
74  * Cannot open file in write mode
75  */
76 define('HTML_JAVASCRIPT_ERROR_WRITEFILE', 506, true);
77
78 //Output modes
79 /**
80  * Just return the results (default mode)
81  */
82 define('HTML_JAVASCRIPT_OUTPUT_RETURN', 1);
83
84 /**
85  * Echo (print) the results directly to browser
86  */
87 define('HTML_JAVASCRIPT_OUTPUT_ECHO', 2);
88
89 /**
90  * Print the results to a file
91  */
92 define('HTML_JAVASCRIPT_OUTPUT_FILE', 3);
93
94 if(!defined('HTML_JAVASCRIPT_NL')){
95     /** Linefeed to use, default set to Unix linefeed.
96      * Define it before the include/require if you want to
97      * override it.
98      */
99     define('HTML_JAVASCRIPT_NL', "\n");
100 }
101
102 /** Convertion tools */
103 require_once 'HTML/Javascript/Convert.php';
104
105 /**
106  * Main Javascript class
107  *
108  * Provides the basic function to output Javascript
109  * scripts, like start and end tags or set the output mode.
110  * @package HTML_Javascript
111  */
112 class HTML_Javascript
113 {
114     /**
115      * Used to determaine if a script has been started
116      *
117      * @var    boolean $_started
118      * @access private
119      */
120     var $_started = false;
121
122     /**
123      * The output mode specified for the script
124      *
125      * @var    integer $_mode
126      * @access private
127      */
128     var $_mode = HTML_JAVASCRIPT_OUTPUT_RETURN;
129
130     /**
131      * The file to direct the output to
132      *
133      * @var    string $_file
134      * @access private
135      */
136     var $_file = '';
137
138       
139     // {{{ setOutputMode
140
141     /**
142      * Set the output mode for the script
143      *
144      * @param  integer  $mode  the chosen output mode, can be either
145      *                         {@link HTML_JAVASCRIPT_OUTPUT_RETURN},
146      *                         {@link HTML_JAVASCRIPT_OUTPUT_ECHO}  or
147      *                         {@link HTML_JAVASCRIPT_OUTPUT_FILE}
148      * @param  string   $file  the path to the file
149      *                         (if $mode is {@link HTML_JAVASCRIPT_OUTPUT_FILE})
150      * @see getOutputMode
151      * @access public
152      * @return mixed    PEAR_Error or true
153      */
154     function setOutputMode($mode = HTML_JAVASCRIPT_OUTPUT_RETURN, $file = NULL)
155     {
156         if($mode == HTML_JAVASCRIPT_OUTPUT_FILE ) {
157             if(isset($file)) {
158                 $this->_file = $file;
159             } else {
160                 $this->raiseError(HTML_JAVASCRIPT_ERROR_NOFILE);
161             }
162         }
163         $this->_mode = $mode;
164         return true;
165     }
166
167     // }}} setOutputMode
168     // {{{ setOutputMode
169
170     /**
171      * Get the output mode for the script
172      *
173      * @see setOutputMode
174      * @access public
175      * @return mixed    PEAR_Error or true
176      */
177     function getOutputMode()
178     {
179
180         return $this->_mode;
181     }
182
183     // }}} setOutputMode
184     // {{{ raiseError
185
186     /**
187      * A custom error handler
188      *
189      * @access private
190      * @param  integer  $code the error code
191      * @return mixed    false if the error code is invalid,
192      *                  or a PEAR_Error otherwise
193      */
194     function raiseError($code)
195     {
196         $ret = null;
197         require_once 'PEAR.php';
198         switch ($code) {
199             case HTML_JAVASCRIPT_ERROR_NOSTART:
200                 $ret = PEAR::raiseError(
201                         'No script started',
202                         HTML_JAVASCRIPT_ERROR_NOSTART
203                         );
204                 break;
205                 
206             case HTML_JAVASCRIPT_ERROR_NOEND:
207                 $ret = PEAR::raiseError(
208                         'Last script was not ended',
209                         HTML_JAVASCRIPT_ERROR_NOEND
210                         );
211                 break;
212                 
213             case HTML_JAVASCRIPT_ERROR_NOFILE:
214                 $ret = PEAR::raiseError(
215                         'A filename must be specified for setoutputMode()',
216                         HTML_JAVASCRIPT_ERROR_NOFILE
217                         );
218                 break;
219                 
220             default:
221                 return PEAR::raiseError(
222                         'Unknown Error',
223                         HTML_JAVASCRIPT_ERROR_UNKNOWN
224                         );
225                 break;
226         }
227
228         return $ret;
229     }
230
231     // }}} raiseError
232     // {{{ startScript
233
234     /**
235      * Starts a new script
236      *
237      * @param  bool     $defer whether to wait for the whole page to load
238      *                  before starting the script or no. Use defer only
239      *                  with script that does not change the document (i.e.
240      *                  alert does not change it).
241      *
242      * @access public
243      * @return mixed    a PEAR_Error if a script has been already started
244      *                  or a string (HTML tag <script>)
245      */
246     function startScript($defer = true)
247     {
248         $this->_started = true;
249         $s      = $defer ? 'defer="defer"' : '';
250         $ret    = "<script type=\"text/javascript\" ".$s.">".
251                     HTML_JAVASCRIPT_NL;
252         return $ret;
253     }
254
255     // }}} startScript
256     // {{{ endScript
257
258     /**
259      * Used to end the script (</script>)
260      *
261      * @return mixed    PEAR_Error if no script has been started
262      *                  or the end tag for the script
263      * @access public
264      */
265     function endScript()
266     {
267         if ($this->_started) {
268             $this->_started = false;
269             $ret =  "</script>".HTML_JAVASCRIPT_NL;
270         } else {
271             $ret =  HTML_Javascript::raiseError(HTML_JAVASCRIPT_ERROR_NOSTART);
272         }
273         return $ret;
274     }
275
276     // }}} endScript
277     //{{{ _out
278
279     /**
280      * Checks the output mode and acts according to it
281      *
282      * @param  string   $str the string returned from the calling function
283      * @return mixed    depends on the output mode,
284      *                  $str if it's HTML_JAVASCRIPT_OUTPUT_RETURN, true otherwise
285      * @access private
286      */
287     function _out($str)
288     {
289         static $fp;
290         if( isset($this) ){
291             $mode = $this->_mode;
292             $file = $this->_file;
293         } else {
294             return $str;
295         }
296         switch($mode) {
297             case HTML_JAVASCRIPT_OUTPUT_RETURN:  
298                 return $str;
299                 break;
300              
301
302             case HTML_JAVASCRIPT_OUTPUT_ECHO: 
303                 echo $str;
304                 return true;
305                 break;
306              
307
308             case HTML_JAVASCRIPT_OUTPUT_FILE:  
309                 if ($fp = @fopen($file, 'ab')){
310                     fwrite($fp, $str);
311                 } else {
312                     HTML_Javascript::raiseError(HTML_JAVASCRIPT_ERROR_WRITEFILE);
313                 }
314                 return true;
315                 break;
316              
317             default:  
318                 HTML_Javascript::raiseError('Invalid output mode');
319                 break;
320              
321         }
322     }
323
324     // }}} _out
325     // {{{ write
326
327     /**
328      * A wrapper for document.writeln
329      *
330      * @access public
331      * @param  string  $str the string to output
332      * @param  boolean $var set to true if $str is a variable name
333      * @return mixed   PEAR_Error if no script was started or the processed string
334      */
335     function write($str, $var = false)
336     {
337         if ($var) {
338             $ret = HTML_Javascript::_out(
339                     'document.writeln('.$str.')'.HTML_JAVASCRIPT_NL
340                     );
341         } else {
342             $ret = HTML_Javascript::_out(
343                         'document.writeln("'.
344                         HTML_Javascript_Convert::escapeString($str).'")'.
345                         HTML_JAVASCRIPT_NL
346                     );
347         }
348         return $ret;
349     }
350
351     // }}} write
352     // {{{ writeLine
353
354     /**
355      * A wrapper for document.writeln with an addtional <br /> tag
356      *
357      * @access public
358      * @param  string  $str the string to output
359      * @param  boolean $var set to true if $str is a variable name
360      * @return mixed   PEAR_Error if no script was started *
361      *                 or the processed string
362      */
363     function writeLine($str, $var = false)
364     {
365         if ($var) {
366             return HTML_Javascript::_out(
367                     'document.writeln('.$str.'+"<br />")'.HTML_JAVASCRIPT_NL
368                     );
369         }
370         
371         return HTML_Javascript::_out(
372                     'document.writeln("'.
373                     HTML_Javascript_Convert::escapeString($str).
374                     '"+"<br />")'.HTML_JAVASCRIPT_NL
375                 );
376         
377     }
378
379     // }}} writeLine
380     // {{{ alert
381
382     /**
383      * A wrapper for alert
384      *
385      * @access public
386      * @param  string    $str the string to output
387      * @param  boolean   $var set to true if $str is a variable name
388      * @return mixed     PEAR_Error if no script was started
389      *                   or the processed string
390      */
391     function alert($str, $var = false)
392     {
393         $alert  = 'alert(';
394         $alert  .= $var?
395                     $str:
396                     '"' . HTML_Javascript_Convert::escapeString($str) . '"';
397         $ret = HTML_Javascript::_out($alert.')'.HTML_JAVASCRIPT_NL);
398         return $ret;
399     }
400
401     // {{{ alert
402     // {{{ confirm
403
404     /**
405      * Create a box with yes and no buttons.
406      * In futur releases, the 1st arg will change, $str will always be the 1st
407      * argument, $assign the 2nd.
408      *
409      * @param  string $assign   the JS variable to assign the confirmation box to
410      * @param  string $str      the string that will appear in the confirmation box
411      * @param  bool   $var      whether $str is a JS var or not
412      * @return string the processed string
413      */
414     function confirm($str,$assign, $var = false)
415     {
416         if($var) {
417             $confirm = 'confirm(' . $str . ')' . HTML_JAVASCRIPT_NL;
418         } else {
419             $confirm = 'confirm("' .
420                 HTML_Javascript_Convert::escapeString($str) . '")' .
421                 HTML_JAVASCRIPT_NL;
422         }
423         $ret = HTML_Javascript::_out($assign . ' = ' . $confirm);
424         return $ret;
425     }
426
427     // }}} confirm
428     // {{{ prompt
429
430     /**
431      * Open a propmt (input box)
432      *
433      * @param  string $str     the string that will appear in the prompt
434      * @param  string $assign  the JS var that the input will be assigned to
435      * @param  string $default the default value
436      * @param  string $var     wether $str is a JS var or not
437      * @return mixed  PEAR_Error or the processed string
438      */
439     function prompt($str, $assign, $default = '', $var = false)
440     {
441         if ($var) {
442             $prompt = 'prompt('.$str.', "'.$default.')"'.HTML_JAVASCRIPT_NL;
443         } else {
444
445             $prompt = 'prompt("'.
446                         HTML_Javascript_Convert::escapeString($str).
447                         '", "'.$default.
448                         '")'.HTML_JAVASCRIPT_NL;
449         }
450         $ret = HTML_Javascript::_out($assign .' = ' . $prompt);
451         return $ret;
452     }
453
454     // }}} prompt
455     // {{{ popup
456
457     /**
458      * A method for easy generation of popup windows
459      *
460      * @param  string $assign   the JS var to assign the window to
461      * @param  string $file     the file that will appear in the new window
462      * @param  string $title    the title of the new window
463      * @param  int    $width    the width of the window
464      * @param  int    $height   the height of the window
465      * @param  mixed  $attr     an array containing the attributes for the new
466      *                          window, each cell can contain either the ints 1/0
467      *                          or the strings 'yes'/'no'.
468      *                          The order of attributes:
469      *                          resizable, scrollbars, menubar, toolbar,
470      *                          status, location.
471      *                          Can be also a boolean, and then all the attributes
472      *                          are set to yes or no, according to the boolean value.
473      * @param  int   $top       the distance from the top, in pixels (only used if attr=false|true).
474      * @param  int   $left      the distance from the left, in pixels (only used if attr=false|true).
475      * @return mixed PEAR_Error on error or the processed string.
476      */
477     function popup(
478         $assign, $file, $title, $width, $height, $attr, $top = 300, $left = 300
479     )
480     {
481         if(!is_array($attr)) {
482             if(!is_bool($attr)) {
483                 PEAR::raiseError('$attr should be either an array or a boolean');
484             } else {
485                 if($attr) {
486                     $attr = array('yes', 'yes', 'yes', 'yes', 'yes', 'yes', $top, $left);
487                 } else {
488                     $attr = array('no', 'no', 'no', 'no', 'no', 'no', $top, $left);
489                 }
490             }
491         }
492         $ret = HTML_Javascript::_out(
493                     $assign .
494                     "= window.open(".
495                     "\"$file\", \"$title\",".
496                     " \"width=$width, height=$height,".
497                     "resizable=$attr[0], scrollbars=$attr[1],".
498                     " menubar=$attr[2], toolbar=$attr[3], status=$attr[4],".
499                     " location=$attr[5], top=$attr[6], left=$attr[7]\")".
500                     HTML_JAVASCRIPT_NL);
501         return $ret;
502     }
503
504     // }}} popup
505     // {{{ popupWrite
506
507     /**
508      * Creates a new popup window containing a string. Inside the popup windows
509      * you can access the opener window with the opener var.
510      *
511      * @param  string $assign   the JS variable to assign the window to
512      * @param  string $str      the string that will appear in the new window
513      *                          (HTML tags would be parsed by the browser, of course)
514      * @param  string $title    the title of the window
515      * @param  int    $width    the width of the window
516      * @param  int    $height   the height of the window
517      * @param  mixed  $attr     see popup()
518      * @param  int    $top      distance from the top (in pixels
519      * @param  int    $left     distance from the left (in pixels)
520      * @see    popup()
521      * @return the processed string
522      */
523     function popupWrite(
524         $assign, $str, $title, $width, $height, $attr, $top = 300, $left = 300
525     )
526     {
527         static  $cnt_popup;
528         $str        = HTML_Javascript_Convert::escapeString($str);
529         $assign     = strlen($assign)==0?'pearpopup'.$cnt_popup++:$assign;
530
531         if($attr) {
532             $attr = array('yes', 'yes', 'yes', 'yes', 'yes', 'yes', $top, $left);
533         } else {
534             $attr = array('no', 'no', 'no', 'no', 'no', 'no', $top, $height);
535         }
536
537         $windows = $assign . "= window.open(\"\",".
538                                 " \"$title\",".
539                                 " \"width=$width, height=$height,".
540                                 " resizable=$attr[0], scrollbars=$attr[1],".
541                                 " menubar=$attr[2], toolbar=$attr[3],".
542                                 " status=$attr[4], location=$attr[5],".
543                                 " top=$attr[6], left=$attr[7]\")".HTML_JAVASCRIPT_NL;
544
545         $windows    .= "
546                         if ($assign){
547                             $assign.focus();
548                             $assign.document.open();
549                             $assign.document.write('$str');
550                             $assign.document.close();
551                             if ($assign.opener == null) $assign.opener = self;
552                         }
553                       ";
554
555         $ret = HTML_Javascript::_out($windows);
556         return $ret;
557     }
558
559     // }}} popupWrite
560 }
561 ?>