Subversion-Projekte lars-tiefland.prado

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
/**
3
 * TClientScriptManager and TClientSideOptions class file.
4
 *
5
 * @author Qiang Xue <qiang.xue@gmail.com>
6
 * @link http://www.pradosoft.com/
7
 * @copyright Copyright &copy; 2005-2008 PradoSoft
8
 * @license http://www.pradosoft.com/license/
9
 * @version $Id: TClientScriptManager.php 2564 2008-11-11 21:56:02Z carlgmathisen $
10
 * @package System.Web.UI
11
 */
12
 
13
/**
14
 * TClientScriptManager class.
15
 *
16
 * TClientScriptManager manages javascript and CSS stylesheets for a page.
17
 *
18
 * @author Qiang Xue <qiang.xue@gmail.com>
19
 * @version $Id: TClientScriptManager.php 2564 2008-11-11 21:56:02Z carlgmathisen $
20
 * @package System.Web.UI
21
 * @since 3.0
22
 */
23
class TClientScriptManager extends TApplicationComponent
24
{
25
	/**
26
	 * directory containing Prado javascript files
27
	 */
28
	const SCRIPT_PATH='Web/Javascripts/source';
29
	/**
30
	 * the PHP script for loading Prado javascript files
31
	 */
32
	const SCRIPT_LOADER='Web/Javascripts/clientscripts.php';
33
 
34
	/**
35
	 * @var TPage page who owns this manager
36
	 */
37
	private $_page;
38
	/**
39
	 * @var array registered hidden fields, indexed by hidden field names
40
	 */
41
	private $_hiddenFields=array();
42
	/**
43
	 * @var array javascript blocks to be rendered at the beginning of the form
44
	 */
45
	private $_beginScripts=array();
46
	/**
47
	 * @var array javascript blocks to be rendered at the end of the form
48
	 */
49
	private $_endScripts=array();
50
	/**
51
	 * @var array javascript files to be rendered in the form
52
	 */
53
	private $_scriptFiles=array();
54
	/**
55
	 * @var array javascript files to be rendered in page head section
56
	 */
57
	private $_headScriptFiles=array();
58
	/**
59
	 * @var array javascript blocks to be rendered in page head section
60
	 */
61
	private $_headScripts=array();
62
	/**
63
	 * @var array CSS files
64
	 */
65
	private $_styleSheetFiles=array();
66
	/**
67
	 * @var array CSS declarations
68
	 */
69
	private $_styleSheets=array();
70
	/**
71
	 * @var array registered PRADO script libraries
72
	 */
73
	private $_registeredPradoScripts=array();
74
	/**
75
	 * Client-side javascript library dependencies, loads from SCRIPT_PATH.'/packages.php';
76
	 * @var array
77
	 */
78
	private static $_pradoScripts;
79
 
80
	/**
81
	 * Constructor.
82
	 * @param TPage page that owns this client script manager
83
	 */
84
	public function __construct(TPage $owner)
85
	{
86
		$this->_page=$owner;
87
	}
88
 
89
	/**
90
	 * @return boolean whether THead is required in order to render CSS and js within head
91
	 * @since 3.1.1
92
	 */
93
	public function getRequiresHead()
94
	{
95
		return count($this->_styleSheetFiles) || count($this->_styleSheets)
96
			|| count($this->_headScriptFiles) || count($this->_headScripts);
97
	}
98
 
99
	/**
100
	 * Registers Prado javascript by library name. See "Web/Javascripts/source/packages.php"
101
	 * for library names.
102
	 * @param string script library name.
103
	 */
104
	public function registerPradoScript($name)
105
	{
106
		$this->registerPradoScriptInternal($name);
107
		$params=func_get_args();
108
		$this->_page->registerCachingAction('Page.ClientScript','registerPradoScript',$params);
109
	}
110
 
111
	/**
112
	 * Registers a Prado javascript library to be loaded.
113
	 */
114
	private function registerPradoScriptInternal($name)
115
	{
116
		if(!isset($this->_registeredPradoScripts[$name]))
117
		{
118
			if(self::$_pradoScripts === null)
119
			{
120
				$packageFile = Prado::getFrameworkPath().DIRECTORY_SEPARATOR.self::SCRIPT_PATH.'/packages.php';
121
				list($packages,$deps)= include($packageFile);
122
				self::$_pradoScripts = $deps;
123
			}
124
 
125
			if(isset(self::$_pradoScripts[$name]))
126
				$this->_registeredPradoScripts[$name]=true;
127
			else
128
				throw new TInvalidOperationException('csmanager_pradoscript_invalid',$name);
129
		}
130
	}
131
 
132
	/**
133
	 * @return string Prado javascript library base asset url.
134
	 */
135
	public function getPradoScriptAssetUrl()
136
	{
137
		$base = Prado::getFrameworkPath().DIRECTORY_SEPARATOR.self::SCRIPT_PATH;
138
		$assets = Prado::getApplication()->getAssetManager();
139
		return $assets->getPublishedUrl($base);
140
	}
141
 
142
	/**
143
	 * Renders the HTML tags for PRADO js files
144
	 * @param THtmlWriter writer
145
	 */
146
	protected function renderPradoScripts($writer)
147
	{
148
		if(($packages=array_keys($this->_registeredPradoScripts))!==array())
149
		{
150
			$base = Prado::getFrameworkPath().DIRECTORY_SEPARATOR.self::SCRIPT_PATH;
151
			$url = $this->registerJavascriptPackages($base, $packages);
152
			$writer->write(TJavaScript::renderScriptFile($url));
153
		}
154
	}
155
 
156
	/**
157
	 * Publishes a javascript library path and register packages to be loaded.
158
	 * See TClientScriptLoader for component that enables users to register custom javascript libraries.
159
	 * @param string javascript library base path
160
	 * @param array list of packages or javascript files (without .js extension) to be loaded.
161
	 * @param boolean true to enable keep comments in javascript files loaded, null to use application configuration.
162
	 * @param boolean true to gzip the javascript code if browsers and php supports it.
163
	 * @return string javascript src url
164
	 * @since 3.1
165
	 */
166
	public function registerJavascriptPackages($base, $packages, $debug=null, $gzip=true)
167
	{
168
		list($path,$url) = $this->getPackagePathUrl($base);
169
		$scriptLoaderPath = $path.'/'.basename(self::SCRIPT_LOADER);
170
		$scriptLoaderSrc = Prado::getFrameworkPath().DIRECTORY_SEPARATOR.self::SCRIPT_LOADER;
171
		if(!is_file($scriptLoaderPath))
172
		{
173
			copy($scriptLoaderSrc, $scriptLoaderPath);
174
			chmod($scriptLoaderPath, PRADO_CHMOD);
175
		}
176
		$url .= '/'.basename(self::SCRIPT_LOADER).'?js='.implode(',', $packages);
177
		if($debug!==false && $this->getApplication()->getMode()===TApplicationMode::Debug)
178
		{
179
			$this->verifyJavascriptPackages($base,$path,$packages);
180
			$url.='&amp;mode=debug';
181
		}
182
		if($gzip===false)
183
			$url.='&amp;gzip=false';
184
		return $url;
185
	}
186
 
187
	/**
188
	 * @throws TConfigurationException when javascript packages mismatch.
189
	 */
190
	protected function verifyJavascriptPackages($base,$path,$scripts)
191
	{
192
		$file = $path.'/packages.php';
193
		if(is_file($file))
194
		{
195
			list($packs,$deps) = include($file);
196
			if(count($missing = array_diff($scripts, array_keys($deps))) > 0)
197
			{
198
				throw new TConfigurationException('csmanager_invalid_packages',
199
					$base.'/packages.php',implode(', ', $missing), implode(', ', array_keys($deps)));
200
			}
201
		}
202
	}
203
 
204
	/**
205
	 * @param string javascript package path.
206
	 * @return array tuple($path,$url).
207
	 */
208
	protected function getPackagePathUrl($base)
209
	{
210
		$assets = Prado::getApplication()->getAssetManager();
211
		if(strpos($base, $assets->getBaseUrl())===false)
212
		{
213
			if(($dir = Prado::getPathOfNameSpace($base)) !== null) {
214
				$base = $dir;
215
			}
216
			return array($assets->getPublishedPath($base), $assets->publishFilePath($base));
217
		}
218
		else
219
		{
220
			return array($assets->getBasePath().str_replace($assets->getBaseUrl(),'',$base), $base);
221
		}
222
	}
223
 
224
	/**
225
	 * Returns javascript statement that create a new callback request object.
226
	 * @param ICallbackEventHandler callback response handler
227
	 * @param array additional callback options
228
	 * @return string javascript statement that creates a new callback request.
229
	 */
230
	public function getCallbackReference(ICallbackEventHandler $callbackHandler, $options=null)
231
	{
232
		$options = !is_array($options) ? array() : $options;
233
		$class = new TReflectionClass($callbackHandler);
234
		$clientSide = $callbackHandler->getActiveControl()->getClientSide();
235
		$options = array_merge($options, $clientSide->getOptions()->toArray());
236
		$optionString = TJavaScript::encode($options);
237
		$this->registerPradoScriptInternal('ajax');
238
		$id = $callbackHandler->getUniqueID();
239
		return "new Prado.CallbackRequest('{$id}',{$optionString})";
240
	}
241
 
242
	/**
243
	 * Registers callback javascript for a control.
244
	 * @param string javascript class responsible for the control being registered for callback
245
	 * @param array callback options
246
	 */
247
	public function registerCallbackControl($class, $options)
248
	{
249
		$optionString=TJavaScript::encode($options);
250
		$code="new {$class}({$optionString});";
251
		$this->_endScripts[sprintf('%08X', crc32($code))]=$code;
252
		$this->registerPradoScriptInternal('ajax');
253
 
254
		$params=func_get_args();
255
		$this->_page->registerCachingAction('Page.ClientScript','registerCallbackControl',$params);
256
	}
257
 
258
	/**
259
	 * Registers postback javascript for a control. A null class parameter will prevent
260
	 * the javascript code registration.
261
	 * @param string javascript class responsible for the control being registered for postback
262
	 * @param array postback options
263
	 */
264
	public function registerPostBackControl($class,$options)
265
	{
266
		if($class === null) {
267
			return;
268
		}
269
		if(!isset($options['FormID']) && ($form=$this->_page->getForm())!==null)
270
			$options['FormID']=$form->getClientID();
271
		$optionString=TJavaScript::encode($options);
272
		$code="new {$class}({$optionString});";
273
 
274
		$this->_endScripts[sprintf('%08X', crc32($code))]=$code;
275
		$this->_hiddenFields[TPage::FIELD_POSTBACK_TARGET]='';
276
		$this->_hiddenFields[TPage::FIELD_POSTBACK_PARAMETER]='';
277
		$this->registerPradoScriptInternal('prado');
278
 
279
		$params=func_get_args();
280
		$this->_page->registerCachingAction('Page.ClientScript','registerPostBackControl',$params);
281
	}
282
 
283
	/**
284
	 * Register a default button to panel. When the $panel is in focus and
285
	 * the 'enter' key is pressed, the $button will be clicked.
286
	 * @param TControl|string panel (or its unique ID) to register the default button action
287
	 * @param TControl|string button (or its unique ID) to trigger a postback
288
	 */
289
	public function registerDefaultButton($panel, $button)
290
	{
291
		$panelID=is_string($panel)?$panel:$panel->getUniqueID();
292
 
293
		if(is_string($button))
294
			$buttonID=$button;
295
		else
296
		{
297
			$button->setIsDefaultButton(true);
298
			$buttonID=$button->getUniqueID();
299
		}
300
		$options = TJavaScript::encode($this->getDefaultButtonOptions($panelID, $buttonID));
301
		$code = "new Prado.WebUI.DefaultButton($options);";
302
 
303
		$this->_endScripts['prado:'.$panelID]=$code;
304
		$this->_hiddenFields[TPage::FIELD_POSTBACK_TARGET]='';
305
		$this->registerPradoScriptInternal('prado');
306
 
307
		$params=array($panelID,$buttonID);
308
		$this->_page->registerCachingAction('Page.ClientScript','registerDefaultButton',$params);
309
	}
310
 
311
	/**
312
	 * @param string the unique ID of the container control
313
	 * @param string the unique ID of the button control
314
	 * @return array default button options.
315
	 */
316
	protected function getDefaultButtonOptions($panelID, $buttonID)
317
	{
318
		$options['Panel'] = TControl::convertUniqueIdToClientId($panelID);
319
		$options['Target'] = TControl::convertUniqueIdToClientId($buttonID);
320
		$options['EventTarget'] = $buttonID;
321
		$options['Event'] = 'click';
322
		return $options;
323
	}
324
 
325
	/**
326
	 * Registers the control to receive default focus.
327
	 * @param string the client ID of the control to receive default focus
328
	 */
329
	public function registerFocusControl($target)
330
	{
331
		$this->registerPradoScriptInternal('effects');
332
		if($target instanceof TControl)
333
			$target=$target->getClientID();
334
		$id = TJavaScript::quoteString($target);
335
		$this->_endScripts['prado:focus'] = 'new Effect.ScrollTo("'.$id.'"); Prado.Element.focus("'.$id.'");';
336
 
337
		$params=func_get_args();
338
		$this->_page->registerCachingAction('Page.ClientScript','registerFocusControl',$params);
339
	}
340
 
341
	/**
342
	 * Registers a CSS file to be rendered in the page head
343
	 *
344
	 * The CSS files in themes are registered in {@link OnPreRenderComplete onPreRenderComplete} if you want to override
345
	 * CSS styles in themes you need to register it after this event is completed.
346
	 *
347
	 * Example:
348
	 * <code>
349
	 * <?php
350
	 * class BasePage extends TPage {
351
	 *   public function onPreRenderComplete($param) {
352
	 *     parent::onPreRenderComplete($param);
353
	 *     $url = 'path/to/your/stylesheet.css';
354
	 *     $this->Page->ClientScript->registerStyleSheetFile($url, $url);
355
	 *   }
356
	 * }
357
	 * ?>
358
	 * </code>
359
	 *
360
	 * @param string a unique key identifying the file
361
	 * @param string URL to the CSS file
362
	 * @param string media type of the CSS (such as 'print', 'screen', etc.). Defaults to empty, meaning the CSS applies to all media types.
363
	 */
364
	public function registerStyleSheetFile($key,$url,$media='')
365
	{
366
		if($media==='')
367
			$this->_styleSheetFiles[$key]=$url;
368
		else
369
			$this->_styleSheetFiles[$key]=array($url,$media);
370
 
371
		$params=func_get_args();
372
		$this->_page->registerCachingAction('Page.ClientScript','registerStyleSheetFile',$params);
373
	}
374
 
375
	/**
376
	 * Registers a CSS block to be rendered in the page head
377
	 * @param string a unique key identifying the CSS block
378
	 * @param string CSS block
379
	 */
380
	public function registerStyleSheet($key,$css,$media='')
381
	{
382
		$this->_styleSheets[$key]=$css;
383
 
384
		$params=func_get_args();
385
		$this->_page->registerCachingAction('Page.ClientScript','registerStyleSheet',$params);
386
	}
387
 
388
	/**
389
	 * Registers a javascript file in the page head
390
	 * @param string a unique key identifying the file
391
	 * @param string URL to the javascript file
392
	 */
393
	public function registerHeadScriptFile($key,$url)
394
	{
395
		$this->_headScriptFiles[$key]=$url;
396
 
397
		$params=func_get_args();
398
		$this->_page->registerCachingAction('Page.ClientScript','registerHeadScriptFile',$params);
399
	}
400
 
401
	/**
402
	 * Registers a javascript block in the page head.
403
	 * @param string a unique key identifying the script block
404
	 * @param string javascript block
405
	 */
406
	public function registerHeadScript($key,$script)
407
	{
408
		$this->_headScripts[$key]=$script;
409
 
410
		$params=func_get_args();
411
		$this->_page->registerCachingAction('Page.ClientScript','registerHeadScript',$params);
412
	}
413
 
414
	/**
415
	 * Registers a javascript file to be rendered within the form
416
	 * @param string a unique key identifying the file
417
	 * @param string URL to the javascript file to be rendered
418
	 */
419
	public function registerScriptFile($key,$url)
420
	{
421
		$this->_scriptFiles[$key]=$url;
422
 
423
		$params=func_get_args();
424
		$this->_page->registerCachingAction('Page.ClientScript','registerScriptFile',$params);
425
	}
426
 
427
	/**
428
	 * Registers a javascript script block at the beginning of the form
429
	 * @param string a unique key identifying the script block
430
	 * @param string javascript block
431
	 */
432
	public function registerBeginScript($key,$script)
433
	{
434
		$this->_beginScripts[$key]=$script;
435
 
436
		$params=func_get_args();
437
		$this->_page->registerCachingAction('Page.ClientScript','registerBeginScript',$params);
438
	}
439
 
440
	/**
441
	 * Registers a javascript script block at the end of the form
442
	 * @param string a unique key identifying the script block
443
	 * @param string javascript block
444
	 */
445
	public function registerEndScript($key,$script)
446
	{
447
		$this->_endScripts[$key]=$script;
448
 
449
		$params=func_get_args();
450
		$this->_page->registerCachingAction('Page.ClientScript','registerEndScript',$params);
451
	}
452
 
453
	/**
454
	 * Registers a hidden field to be rendered in the form.
455
	 * @param string a unique key identifying the hidden field
456
	 * @param string|array hidden field value, if the value is an array, every element
457
	 * in the array will be rendered as a hidden field value.
458
	 */
459
	public function registerHiddenField($name,$value)
460
	{
461
		$this->_hiddenFields[$name]=$value;
462
 
463
		$params=func_get_args();
464
		$this->_page->registerCachingAction('Page.ClientScript','registerHiddenField',$params);
465
	}
466
 
467
	/**
468
	 * @param string a unique key
469
	 * @return boolean whether there is a CSS file registered with the specified key
470
	 */
471
	public function isStyleSheetFileRegistered($key)
472
	{
473
		return isset($this->_styleSheetFiles[$key]);
474
	}
475
 
476
	/**
477
	 * @param string a unique key
478
	 * @return boolean whether there is a CSS block registered with the specified key
479
	 */
480
	public function isStyleSheetRegistered($key)
481
	{
482
		return isset($this->_styleSheets[$key]);
483
	}
484
 
485
	/**
486
	 * @param string a unique key
487
	 * @return boolean whether there is a head javascript file registered with the specified key
488
	 */
489
	public function isHeadScriptFileRegistered($key)
490
	{
491
		return isset($this->_headScriptFiles[$key]);
492
	}
493
 
494
	/**
495
	 * @param string a unique key
496
	 * @return boolean whether there is a head javascript block registered with the specified key
497
	 */
498
	public function isHeadScriptRegistered($key)
499
	{
500
		return isset($this->_headScripts[$key]);
501
	}
502
 
503
	/**
504
	 * @param string a unique key
505
	 * @return boolean whether there is a javascript file registered with the specified key
506
	 */
507
	public function isScriptFileRegistered($key)
508
	{
509
		return isset($this->_scriptFiles[$key]);
510
	}
511
 
512
	/**
513
	 * @param string a unique key
514
	 * @return boolean whether there is a beginning javascript block registered with the specified key
515
	 */
516
	public function isBeginScriptRegistered($key)
517
	{
518
		return isset($this->_beginScripts[$key]);
519
	}
520
 
521
	/**
522
	 * @param string a unique key
523
	 * @return boolean whether there is an ending javascript block registered with the specified key
524
	 */
525
	public function isEndScriptRegistered($key)
526
	{
527
		return isset($this->_endScripts[$key]);
528
	}
529
 
530
	/**
531
	 * @return boolean true if any end scripts are registered.
532
	 */
533
	public function hasEndScripts()
534
	{
535
		return count($this->_endScripts) > 0;
536
	}
537
 
538
	/**
539
	 * @return boolean true if any begin scripts are registered.
540
	 */
541
	public function hasBeginScripts()
542
	{
543
		return count($this->_beginScripts) > 0;
544
	}
545
 
546
	/**
547
	 * @param string a unique key
548
	 * @return boolean whether there is a hidden field registered with the specified key
549
	 */
550
	public function isHiddenFieldRegistered($key)
551
	{
552
		return isset($this->_hiddenFields[$key]);
553
	}
554
 
555
	/**
556
	 * @param THtmlWriter writer for the rendering purpose
557
	 */
558
	public function renderStyleSheetFiles($writer)
559
	{
560
		$str='';
561
		foreach($this->_styleSheetFiles as $url)
562
		{
563
			if(is_array($url))
564
				$str.="<link rel=\"stylesheet\" type=\"text/css\" media=\"{$url[1]}\" href=\"".THttpUtility::htmlEncode($url[0])."\" />\n";
565
			else
566
				$str.="<link rel=\"stylesheet\" type=\"text/css\" href=\"".THttpUtility::htmlEncode($url)."\" />\n";
567
		}
568
		$writer->write($str);
569
	}
570
 
571
	/**
572
	 * @param THtmlWriter writer for the rendering purpose
573
	 */
574
	public function renderStyleSheets($writer)
575
	{
576
		if(count($this->_styleSheets))
577
			$writer->write("<style type=\"text/css\">\n/*<![CDATA[*/\n".implode("\n",$this->_styleSheets)."\n/*]]>*/\n</style>\n");
578
	}
579
 
580
	/**
581
	 * @param THtmlWriter writer for the rendering purpose
582
	 */
583
	public function renderHeadScriptFiles($writer)
584
	{
585
		$writer->write(TJavaScript::renderScriptFiles($this->_headScriptFiles));
586
	}
587
 
588
	/**
589
	 * @param THtmlWriter writer for the rendering purpose
590
	 */
591
	public function renderHeadScripts($writer)
592
	{
593
		$writer->write(TJavaScript::renderScriptBlocks($this->_headScripts));
594
	}
595
 
596
	/**
597
	 * @param THtmlWriter writer for the rendering purpose
598
	 */
599
	public function renderScriptFiles($writer)
600
	{
601
		$this->renderPradoScripts($writer);
602
		if(!empty($this->_scriptFiles))
603
			$writer->write(TJavaScript::renderScriptFiles($this->_scriptFiles));
604
	}
605
 
606
	/**
607
	 * @param THtmlWriter writer for the rendering purpose
608
	 */
609
	public function renderBeginScripts($writer)
610
	{
611
		$writer->write(TJavaScript::renderScriptBlocks($this->_beginScripts));
612
	}
613
 
614
	/**
615
	 * @param THtmlWriter writer for the rendering purpose
616
	 */
617
	public function renderEndScripts($writer)
618
	{
619
		$writer->write(TJavaScript::renderScriptBlocks($this->_endScripts));
620
	}
621
 
622
	/**
623
	 * @param THtmlWriter writer for the rendering purpose
624
	 */
625
	public function renderHiddenFields($writer)
626
	{
627
		$str='';
628
		foreach($this->_hiddenFields as $name=>$value)
629
		{
630
			$id=strtr($name,':','_');
631
			if(is_array($value))
632
			{
633
				foreach($value as $v)
634
					$str.='<input type="hidden" name="'.$name.'[]" id="'.$id.'" value="'.THttpUtility::htmlEncode($value)."\" />\n";
635
			}
636
			else
637
			{
638
				$str.='<input type="hidden" name="'.$name.'" id="'.$id.'" value="'.THttpUtility::htmlEncode($value)."\" />\n";
639
			}
640
		}
641
		if($str!=='')
642
			$writer->write("<div style=\"visibility:hidden;\">\n".$str."</div>\n");
643
	}
644
}
645
 
646
/**
647
 * TClientSideOptions abstract class.
648
 *
649
 * TClientSideOptions manages client-side options for components that have
650
 * common client-side javascript behaviours and client-side events such as
651
 * between ActiveControls and validators.
652
 *
653
 * @author <weizhuo[at]gmail[dot]com>
654
 * @version $Id: TClientScriptManager.php 2564 2008-11-11 21:56:02Z carlgmathisen $
655
 * @package System.Web.UI
656
 * @since 3.0
657
 */
658
abstract class TClientSideOptions extends TComponent
659
{
660
	/**
661
	 * @var TMap list of client-side options.
662
	 */
663
	private $_options;
664
 
665
	/**
666
	 * Constructor, initialize the options list.
667
	 */
668
	public function __construct()
669
	{
670
		$this->_options = Prado::createComponent('System.Collections.TMap');
671
	}
672
 
673
	/**
674
	 * Adds on client-side event handler by wrapping the code within a
675
	 * javascript function block. If the code begins with "javascript:", the
676
	 * code is assumed to be a javascript function block rather than arbiturary
677
	 * javascript statements.
678
	 * @param string option name
679
	 * @param string javascript statements.
680
	 */
681
	protected function setFunction($name, $code)
682
	{
683
		if(!TJavaScript::isFunction($code))
684
			$code = TJavaScript::quoteFunction($this->ensureFunction($code));
685
		$this->setOption($name, $code);
686
	}
687
 
688
	/**
689
	 * @return string gets a particular option, null if not set.
690
	 */
691
	protected function getOption($name)
692
	{
693
		return $this->_options->itemAt($name);
694
	}
695
 
696
	/**
697
	 * @param string option name
698
	 * @param mixed option value.
699
	 */
700
	protected function setOption($name, $value)
701
	{
702
		$this->_options->add($name, $value);
703
	}
704
 
705
	/**
706
	 * @return TMap gets the list of options as TMap
707
	 */
708
	public function getOptions()
709
	{
710
		return $this->_options;
711
	}
712
 
713
	/**
714
	 * Ensure that the javascript statements are wrapped in a javascript
715
	 * function block as <code>function(sender, parameter){ //code }</code>.
716
	 */
717
	protected function ensureFunction($javascript)
718
	{
719
		return "function(sender, parameter){ {$javascript} }";
720
	}
721
}
722