1<?php
2/**
3 * CodeIgniter
4 *
5 * An open source application development framework for PHP
6 *
7 * This content is released under the MIT License (MIT)
8 *
9 * Copyright (c) 2014 - 2019, British Columbia Institute of Technology
10 *
11 * Permission is hereby granted, free of charge, to any person obtaining a copy
12 * of this software and associated documentation files (the "Software"), to deal
13 * in the Software without restriction, including without limitation the rights
14 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 * copies of the Software, and to permit persons to whom the Software is
16 * furnished to do so, subject to the following conditions:
17 *
18 * The above copyright notice and this permission notice shall be included in
19 * all copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27 * THE SOFTWARE.
28 *
29 * @package	CodeIgniter
30 * @author	EllisLab Dev Team
31 * @copyright	Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
32 * @copyright	Copyright (c) 2014 - 2019, British Columbia Institute of Technology (http://bcit.ca/)
33 * @license	http://opensource.org/licenses/MIT	MIT License
34 * @link	https://codeigniter.com
35 * @since	Version 1.0.0
36 * @filesource
37 */
38defined('BASEPATH') OR exit('No direct script access allowed');
39
40/**
41 * Javascript Class
42 *
43 * @package		CodeIgniter
44 * @subpackage	Libraries
45 * @category	Javascript
46 * @author		EllisLab Dev Team
47 * @link		https://codeigniter.com/user_guide/libraries/javascript.html
48 * @deprecated	3.0.0	This was never a good idea in the first place.
49 */
50class CI_Javascript {
51
52	/**
53	 * JavaScript location
54	 *
55	 * @var	string
56	 */
57	protected $_javascript_location = 'js';
58
59	// --------------------------------------------------------------------
60
61	/**
62	 * Constructor
63	 *
64	 * @param	array	$params
65	 * @return	void
66	 */
67	public function __construct($params = array())
68	{
69		$defaults = array('js_library_driver' => 'jquery', 'autoload' => TRUE);
70
71		foreach ($defaults as $key => $val)
72		{
73			if (isset($params[$key]) && $params[$key] !== '')
74			{
75				$defaults[$key] = $params[$key];
76			}
77		}
78
79		extract($defaults);
80
81		$this->CI =& get_instance();
82
83		// load the requested js library
84		$this->CI->load->library('Javascript/'.$js_library_driver, array('autoload' => $autoload));
85		// make js to refer to current library
86		$this->js =& $this->CI->$js_library_driver;
87
88		log_message('info', 'Javascript Class Initialized and loaded. Driver used: '.$js_library_driver);
89	}
90
91	// --------------------------------------------------------------------
92	// Event Code
93	// --------------------------------------------------------------------
94
95	/**
96	 * Blur
97	 *
98	 * Outputs a javascript library blur event
99	 *
100	 * @param	string	The element to attach the event to
101	 * @param	string	The code to execute
102	 * @return	string
103	 */
104	public function blur($element = 'this', $js = '')
105	{
106		return $this->js->_blur($element, $js);
107	}
108
109	// --------------------------------------------------------------------
110
111	/**
112	 * Change
113	 *
114	 * Outputs a javascript library change event
115	 *
116	 * @param	string	The element to attach the event to
117	 * @param	string	The code to execute
118	 * @return	string
119	 */
120	public function change($element = 'this', $js = '')
121	{
122		return $this->js->_change($element, $js);
123	}
124
125	// --------------------------------------------------------------------
126
127	/**
128	 * Click
129	 *
130	 * Outputs a javascript library click event
131	 *
132	 * @param	string	The element to attach the event to
133	 * @param	string	The code to execute
134	 * @param	bool	whether or not to return false
135	 * @return	string
136	 */
137	public function click($element = 'this', $js = '', $ret_false = TRUE)
138	{
139		return $this->js->_click($element, $js, $ret_false);
140	}
141
142	// --------------------------------------------------------------------
143
144	/**
145	 * Double Click
146	 *
147	 * Outputs a javascript library dblclick event
148	 *
149	 * @param	string	The element to attach the event to
150	 * @param	string	The code to execute
151	 * @return	string
152	 */
153	public function dblclick($element = 'this', $js = '')
154	{
155		return $this->js->_dblclick($element, $js);
156	}
157
158	// --------------------------------------------------------------------
159
160	/**
161	 * Error
162	 *
163	 * Outputs a javascript library error event
164	 *
165	 * @param	string	The element to attach the event to
166	 * @param	string	The code to execute
167	 * @return	string
168	 */
169	public function error($element = 'this', $js = '')
170	{
171		return $this->js->_error($element, $js);
172	}
173
174	// --------------------------------------------------------------------
175
176	/**
177	 * Focus
178	 *
179	 * Outputs a javascript library focus event
180	 *
181	 * @param	string	The element to attach the event to
182	 * @param	string	The code to execute
183	 * @return	string
184	 */
185	public function focus($element = 'this', $js = '')
186	{
187		return $this->js->_focus($element, $js);
188	}
189
190	// --------------------------------------------------------------------
191
192	/**
193	 * Hover
194	 *
195	 * Outputs a javascript library hover event
196	 *
197	 * @param	string	- element
198	 * @param	string	- Javascript code for mouse over
199	 * @param	string	- Javascript code for mouse out
200	 * @return	string
201	 */
202	public function hover($element = 'this', $over = '', $out = '')
203	{
204		return $this->js->_hover($element, $over, $out);
205	}
206
207	// --------------------------------------------------------------------
208
209	/**
210	 * Keydown
211	 *
212	 * Outputs a javascript library keydown event
213	 *
214	 * @param	string	The element to attach the event to
215	 * @param	string	The code to execute
216	 * @return	string
217	 */
218	public function keydown($element = 'this', $js = '')
219	{
220		return $this->js->_keydown($element, $js);
221	}
222
223	// --------------------------------------------------------------------
224
225	/**
226	 * Keyup
227	 *
228	 * Outputs a javascript library keydown event
229	 *
230	 * @param	string	The element to attach the event to
231	 * @param	string	The code to execute
232	 * @return	string
233	 */
234	public function keyup($element = 'this', $js = '')
235	{
236		return $this->js->_keyup($element, $js);
237	}
238
239	// --------------------------------------------------------------------
240
241	/**
242	 * Load
243	 *
244	 * Outputs a javascript library load event
245	 *
246	 * @param	string	The element to attach the event to
247	 * @param	string	The code to execute
248	 * @return	string
249	 */
250	public function load($element = 'this', $js = '')
251	{
252		return $this->js->_load($element, $js);
253	}
254
255	// --------------------------------------------------------------------
256
257	/**
258	 * Mousedown
259	 *
260	 * Outputs a javascript library mousedown event
261	 *
262	 * @param	string	The element to attach the event to
263	 * @param	string	The code to execute
264	 * @return	string
265	 */
266	public function mousedown($element = 'this', $js = '')
267	{
268		return $this->js->_mousedown($element, $js);
269	}
270
271	// --------------------------------------------------------------------
272
273	/**
274	 * Mouse Out
275	 *
276	 * Outputs a javascript library mouseout event
277	 *
278	 * @param	string	The element to attach the event to
279	 * @param	string	The code to execute
280	 * @return	string
281	 */
282	public function mouseout($element = 'this', $js = '')
283	{
284		return $this->js->_mouseout($element, $js);
285	}
286
287	// --------------------------------------------------------------------
288
289	/**
290	 * Mouse Over
291	 *
292	 * Outputs a javascript library mouseover event
293	 *
294	 * @param	string	The element to attach the event to
295	 * @param	string	The code to execute
296	 * @return	string
297	 */
298	public function mouseover($element = 'this', $js = '')
299	{
300		return $this->js->_mouseover($element, $js);
301	}
302
303	// --------------------------------------------------------------------
304
305	/**
306	 * Mouseup
307	 *
308	 * Outputs a javascript library mouseup event
309	 *
310	 * @param	string	The element to attach the event to
311	 * @param	string	The code to execute
312	 * @return	string
313	 */
314	public function mouseup($element = 'this', $js = '')
315	{
316		return $this->js->_mouseup($element, $js);
317	}
318
319	// --------------------------------------------------------------------
320
321	/**
322	 * Output
323	 *
324	 * Outputs the called javascript to the screen
325	 *
326	 * @param	string	The code to output
327	 * @return	string
328	 */
329	public function output($js)
330	{
331		return $this->js->_output($js);
332	}
333
334	// --------------------------------------------------------------------
335
336	/**
337	 * Ready
338	 *
339	 * Outputs a javascript library mouseup event
340	 *
341	 * @param	string	$js	Code to execute
342	 * @return	string
343	 */
344	public function ready($js)
345	{
346		return $this->js->_document_ready($js);
347	}
348
349	// --------------------------------------------------------------------
350
351	/**
352	 * Resize
353	 *
354	 * Outputs a javascript library resize event
355	 *
356	 * @param	string	The element to attach the event to
357	 * @param	string	The code to execute
358	 * @return	string
359	 */
360	public function resize($element = 'this', $js = '')
361	{
362		return $this->js->_resize($element, $js);
363	}
364
365	// --------------------------------------------------------------------
366
367	/**
368	 * Scroll
369	 *
370	 * Outputs a javascript library scroll event
371	 *
372	 * @param	string	The element to attach the event to
373	 * @param	string	The code to execute
374	 * @return	string
375	 */
376	public function scroll($element = 'this', $js = '')
377	{
378		return $this->js->_scroll($element, $js);
379	}
380
381	// --------------------------------------------------------------------
382
383	/**
384	 * Unload
385	 *
386	 * Outputs a javascript library unload event
387	 *
388	 * @param	string	The element to attach the event to
389	 * @param	string	The code to execute
390	 * @return	string
391	 */
392	public function unload($element = 'this', $js = '')
393	{
394		return $this->js->_unload($element, $js);
395	}
396
397	// --------------------------------------------------------------------
398	// Effects
399	// --------------------------------------------------------------------
400
401	/**
402	 * Add Class
403	 *
404	 * Outputs a javascript library addClass event
405	 *
406	 * @param	string	- element
407	 * @param	string	- Class to add
408	 * @return	string
409	 */
410	public function addClass($element = 'this', $class = '')
411	{
412		return $this->js->_addClass($element, $class);
413	}
414
415	// --------------------------------------------------------------------
416
417	/**
418	 * Animate
419	 *
420	 * Outputs a javascript library animate event
421	 *
422	 * @param	string	$element = 'this'
423	 * @param	array	$params = array()
424	 * @param	mixed	$speed			'slow', 'normal', 'fast', or time in milliseconds
425	 * @param	string	$extra
426	 * @return	string
427	 */
428	public function animate($element = 'this', $params = array(), $speed = '', $extra = '')
429	{
430		return $this->js->_animate($element, $params, $speed, $extra);
431	}
432
433	// --------------------------------------------------------------------
434
435	/**
436	 * Fade In
437	 *
438	 * Outputs a javascript library hide event
439	 *
440	 * @param	string	- element
441	 * @param	string	- One of 'slow', 'normal', 'fast', or time in milliseconds
442	 * @param	string	- Javascript callback function
443	 * @return	string
444	 */
445	public function fadeIn($element = 'this', $speed = '', $callback = '')
446	{
447		return $this->js->_fadeIn($element, $speed, $callback);
448	}
449
450	// --------------------------------------------------------------------
451
452	/**
453	 * Fade Out
454	 *
455	 * Outputs a javascript library hide event
456	 *
457	 * @param	string	- element
458	 * @param	string	- One of 'slow', 'normal', 'fast', or time in milliseconds
459	 * @param	string	- Javascript callback function
460	 * @return	string
461	 */
462	public function fadeOut($element = 'this', $speed = '', $callback = '')
463	{
464		return $this->js->_fadeOut($element, $speed, $callback);
465	}
466	// --------------------------------------------------------------------
467
468	/**
469	 * Slide Up
470	 *
471	 * Outputs a javascript library slideUp event
472	 *
473	 * @param	string	- element
474	 * @param	string	- One of 'slow', 'normal', 'fast', or time in milliseconds
475	 * @param	string	- Javascript callback function
476	 * @return	string
477	 */
478	public function slideUp($element = 'this', $speed = '', $callback = '')
479	{
480		return $this->js->_slideUp($element, $speed, $callback);
481
482	}
483
484	// --------------------------------------------------------------------
485
486	/**
487	 * Remove Class
488	 *
489	 * Outputs a javascript library removeClass event
490	 *
491	 * @param	string	- element
492	 * @param	string	- Class to add
493	 * @return	string
494	 */
495	public function removeClass($element = 'this', $class = '')
496	{
497		return $this->js->_removeClass($element, $class);
498	}
499
500	// --------------------------------------------------------------------
501
502	/**
503	 * Slide Down
504	 *
505	 * Outputs a javascript library slideDown event
506	 *
507	 * @param	string	- element
508	 * @param	string	- One of 'slow', 'normal', 'fast', or time in milliseconds
509	 * @param	string	- Javascript callback function
510	 * @return	string
511	 */
512	public function slideDown($element = 'this', $speed = '', $callback = '')
513	{
514		return $this->js->_slideDown($element, $speed, $callback);
515	}
516
517	// --------------------------------------------------------------------
518
519	/**
520	 * Slide Toggle
521	 *
522	 * Outputs a javascript library slideToggle event
523	 *
524	 * @param	string	- element
525	 * @param	string	- One of 'slow', 'normal', 'fast', or time in milliseconds
526	 * @param	string	- Javascript callback function
527	 * @return	string
528	 */
529	public function slideToggle($element = 'this', $speed = '', $callback = '')
530	{
531		return $this->js->_slideToggle($element, $speed, $callback);
532
533	}
534
535	// --------------------------------------------------------------------
536
537	/**
538	 * Hide
539	 *
540	 * Outputs a javascript library hide action
541	 *
542	 * @param	string	- element
543	 * @param	string	- One of 'slow', 'normal', 'fast', or time in milliseconds
544	 * @param	string	- Javascript callback function
545	 * @return	string
546	 */
547	public function hide($element = 'this', $speed = '', $callback = '')
548	{
549		return $this->js->_hide($element, $speed, $callback);
550	}
551
552	// --------------------------------------------------------------------
553
554	/**
555	 * Toggle
556	 *
557	 * Outputs a javascript library toggle event
558	 *
559	 * @param	string	- element
560	 * @return	string
561	 */
562	public function toggle($element = 'this')
563	{
564		return $this->js->_toggle($element);
565
566	}
567
568	// --------------------------------------------------------------------
569
570	/**
571	 * Toggle Class
572	 *
573	 * Outputs a javascript library toggle class event
574	 *
575	 * @param	string	$element = 'this'
576	 * @param	string	$class = ''
577	 * @return	string
578	 */
579	public function toggleClass($element = 'this', $class = '')
580	{
581		return $this->js->_toggleClass($element, $class);
582	}
583
584	// --------------------------------------------------------------------
585
586	/**
587	 * Show
588	 *
589	 * Outputs a javascript library show event
590	 *
591	 * @param	string	- element
592	 * @param	string	- One of 'slow', 'normal', 'fast', or time in milliseconds
593	 * @param	string	- Javascript callback function
594	 * @return	string
595	 */
596	public function show($element = 'this', $speed = '', $callback = '')
597	{
598		return $this->js->_show($element, $speed, $callback);
599	}
600
601	// --------------------------------------------------------------------
602
603	/**
604	 * Compile
605	 *
606	 * gather together all script needing to be output
607	 *
608	 * @param	string	$view_var
609	 * @param	bool	$script_tags
610	 * @return	string
611	 */
612	public function compile($view_var = 'script_foot', $script_tags = TRUE)
613	{
614		$this->js->_compile($view_var, $script_tags);
615	}
616
617	// --------------------------------------------------------------------
618
619	/**
620	 * Clear Compile
621	 *
622	 * Clears any previous javascript collected for output
623	 *
624	 * @return	void
625	 */
626	public function clear_compile()
627	{
628		$this->js->_clear_compile();
629	}
630
631	// --------------------------------------------------------------------
632
633	/**
634	 * External
635	 *
636	 * Outputs a <script> tag with the source as an external js file
637	 *
638	 * @param	string	$external_file
639	 * @param	bool	$relative
640	 * @return	string
641	 */
642	public function external($external_file = '', $relative = FALSE)
643	{
644		if ($external_file !== '')
645		{
646			$this->_javascript_location = $external_file;
647		}
648		elseif ($this->CI->config->item('javascript_location') !== '')
649		{
650			$this->_javascript_location = $this->CI->config->item('javascript_location');
651		}
652
653		if ($relative === TRUE OR strpos($external_file, 'http://') === 0 OR strpos($external_file, 'https://') === 0)
654		{
655			$str = $this->_open_script($external_file);
656		}
657		elseif (strpos($this->_javascript_location, 'http://') !== FALSE)
658		{
659			$str = $this->_open_script($this->_javascript_location.$external_file);
660		}
661		else
662		{
663			$str = $this->_open_script($this->CI->config->slash_item('base_url').$this->_javascript_location.$external_file);
664		}
665
666		return $str.$this->_close_script();
667	}
668
669	// --------------------------------------------------------------------
670
671	/**
672	 * Inline
673	 *
674	 * Outputs a <script> tag
675	 *
676	 * @param	string	The element to attach the event to
677	 * @param	bool	If a CDATA section should be added
678	 * @return	string
679	 */
680	public function inline($script, $cdata = TRUE)
681	{
682		return $this->_open_script()
683			. ($cdata ? "\n// <![CDATA[\n".$script."\n// ]]>\n" : "\n".$script."\n")
684			. $this->_close_script();
685	}
686
687	// --------------------------------------------------------------------
688
689	/**
690	 * Open Script
691	 *
692	 * Outputs an opening <script>
693	 *
694	 * @param	string
695	 * @return	string
696	 */
697	protected function _open_script($src = '')
698	{
699		return '<script type="text/javascript" charset="'.strtolower($this->CI->config->item('charset')).'"'
700			.($src === '' ? '>' : ' src="'.$src.'">');
701	}
702
703	// --------------------------------------------------------------------
704
705	/**
706	 * Close Script
707	 *
708	 * Outputs an closing </script>
709	 *
710	 * @param	string
711	 * @return	string
712	 */
713	protected function _close_script($extra = "\n")
714	{
715		return '</script>'.$extra;
716	}
717
718	// --------------------------------------------------------------------
719	// AJAX-Y STUFF - still a testbed
720	// --------------------------------------------------------------------
721
722	/**
723	 * Update
724	 *
725	 * Outputs a javascript library slideDown event
726	 *
727	 * @param	string	- element
728	 * @param	string	- One of 'slow', 'normal', 'fast', or time in milliseconds
729	 * @param	string	- Javascript callback function
730	 * @return	string
731	 */
732	public function update($element = 'this', $speed = '', $callback = '')
733	{
734		return $this->js->_updater($element, $speed, $callback);
735	}
736
737	// --------------------------------------------------------------------
738
739	/**
740	 * Generate JSON
741	 *
742	 * Can be passed a database result or associative array and returns a JSON formatted string
743	 *
744	 * @param	mixed	result set or array
745	 * @param	bool	match array types (defaults to objects)
746	 * @return	string	a json formatted string
747	 */
748	public function generate_json($result = NULL, $match_array_type = FALSE)
749	{
750		// JSON data can optionally be passed to this function
751		// either as a database result object or an array, or a user supplied array
752		if ($result !== NULL)
753		{
754			if (is_object($result))
755			{
756				$json_result = is_callable(array($result, 'result_array')) ? $result->result_array() : (array) $result;
757			}
758			elseif (is_array($result))
759			{
760				$json_result = $result;
761			}
762			else
763			{
764				return $this->_prep_args($result);
765			}
766		}
767		else
768		{
769			return 'null';
770		}
771
772		$json = array();
773		$_is_assoc = TRUE;
774
775		if ( ! is_array($json_result) && empty($json_result))
776		{
777			show_error('Generate JSON Failed - Illegal key, value pair.');
778		}
779		elseif ($match_array_type)
780		{
781			$_is_assoc = $this->_is_associative_array($json_result);
782		}
783
784		foreach ($json_result as $k => $v)
785		{
786			if ($_is_assoc)
787			{
788				$json[] = $this->_prep_args($k, TRUE).':'.$this->generate_json($v, $match_array_type);
789			}
790			else
791			{
792				$json[] = $this->generate_json($v, $match_array_type);
793			}
794		}
795
796		$json = implode(',', $json);
797
798		return $_is_assoc ? '{'.$json.'}' : '['.$json.']';
799
800	}
801
802	// --------------------------------------------------------------------
803
804	/**
805	 * Is associative array
806	 *
807	 * Checks for an associative array
808	 *
809	 * @param	array
810	 * @return	bool
811	 */
812	protected function _is_associative_array($arr)
813	{
814		foreach (array_keys($arr) as $key => $val)
815		{
816			if ($key !== $val)
817			{
818				return TRUE;
819			}
820		}
821
822		return FALSE;
823	}
824
825	// --------------------------------------------------------------------
826
827	/**
828	 * Prep Args
829	 *
830	 * Ensures a standard json value and escapes values
831	 *
832	 * @param	mixed	$result
833	 * @param	bool	$is_key = FALSE
834	 * @return	string
835	 */
836	protected function _prep_args($result, $is_key = FALSE)
837	{
838		if ($result === NULL)
839		{
840			return 'null';
841		}
842		elseif (is_bool($result))
843		{
844			return ($result === TRUE) ? 'true' : 'false';
845		}
846		elseif (is_string($result) OR $is_key)
847		{
848			return '"'.str_replace(array('\\', "\t", "\n", "\r", '"', '/'), array('\\\\', '\\t', '\\n', "\\r", '\"', '\/'), $result).'"';
849		}
850		elseif (is_scalar($result))
851		{
852			return $result;
853		}
854	}
855
856}
857