PageRenderTime 53ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/libraries/joomla/html/html/behavior.php

https://bitbucket.org/organicdevelopment/joomla-2.5
PHP | 959 lines | 692 code | 68 blank | 199 comment | 40 complexity | a58bb4dc1f92961d0e24eef3357328c2 MD5 | raw file
Possible License(s): LGPL-3.0, GPL-2.0, MIT, BSD-3-Clause, LGPL-2.1
  1. <?php
  2. /**
  3. * @package Joomla.Platform
  4. * @subpackage HTML
  5. *
  6. * @copyright Copyright (C) 2005 - 2012 Open Source Matters, Inc. All rights reserved.
  7. * @license GNU General Public License version 2 or later; see LICENSE
  8. */
  9. defined('JPATH_PLATFORM') or die;
  10. /**
  11. * Utility class for javascript behaviors
  12. *
  13. * @package Joomla.Platform
  14. * @subpackage HTML
  15. * @since 11.1
  16. */
  17. abstract class JHtmlBehavior
  18. {
  19. /**
  20. * @var array array containing information for loaded files
  21. */
  22. protected static $loaded = array();
  23. /**
  24. * Method to load the MooTools framework into the document head
  25. *
  26. * If debugging mode is on an uncompressed version of MooTools is included for easier debugging.
  27. *
  28. * @param string $extras MooTools file to load
  29. * @param boolean $debug Is debugging mode on? [optional]
  30. *
  31. * @return void
  32. *
  33. * @since 11.1
  34. */
  35. public static function framework($extras = false, $debug = null)
  36. {
  37. $type = $extras ? 'more' : 'core';
  38. // Only load once
  39. if (!empty(self::$loaded[__METHOD__][$type]))
  40. {
  41. return;
  42. }
  43. // If no debugging value is set, use the configuration setting
  44. if ($debug === null)
  45. {
  46. $config = JFactory::getConfig();
  47. $debug = $config->get('debug');
  48. }
  49. if ($type != 'core' && empty(self::$loaded[__METHOD__]['core']))
  50. {
  51. self::framework(false, $debug);
  52. }
  53. JHtml::_('script', 'system/mootools-' . $type . '.js', false, true, false, false, $debug);
  54. JHtml::_('script', 'system/core.js', false, true);
  55. self::$loaded[__METHOD__][$type] = true;
  56. return;
  57. }
  58. /**
  59. * Deprecated. Use JHtmlBehavior::framework() instead.
  60. *
  61. * @param boolean $debug Is debugging mode on? [optional]
  62. *
  63. * @return void
  64. *
  65. * @since 11.1
  66. *
  67. * @deprecated 12.1
  68. */
  69. public static function mootools($debug = null)
  70. {
  71. // Deprecation warning.
  72. JLog::add('JBehavior::mootools is deprecated.', JLog::WARNING, 'deprecated');
  73. self::framework(true, $debug);
  74. }
  75. /**
  76. * Add unobtrusive javascript support for image captions.
  77. *
  78. * @param string $selector The selector for which a caption behaviour is to be applied.
  79. *
  80. * @return void
  81. *
  82. * @since 11.1
  83. */
  84. public static function caption($selector = 'img.caption')
  85. {
  86. // Only load once
  87. if (isset(self::$loaded[__METHOD__][$selector]))
  88. {
  89. return;
  90. }
  91. // Include MooTools framework
  92. self::framework();
  93. JHtml::_('script', 'system/caption.js', true, true);
  94. // Attach caption to document
  95. JFactory::getDocument()->addScriptDeclaration(
  96. "window.addEvent('load', function() {
  97. new JCaption('" . $selector . "');
  98. });"
  99. );
  100. // Set static array
  101. self::$loaded[__METHOD__][$selector] = true;
  102. }
  103. /**
  104. * Add unobtrusive javascript support for form validation.
  105. *
  106. * To enable form validation the form tag must have class="form-validate".
  107. * Each field that needs to be validated needs to have class="validate".
  108. * Additional handlers can be added to the handler for username, password,
  109. * numeric and email. To use these add class="validate-email" and so on.
  110. *
  111. * @return void
  112. *
  113. * @since 11.1
  114. */
  115. public static function formvalidation()
  116. {
  117. // Only load once
  118. if (isset(self::$loaded[__METHOD__]))
  119. {
  120. return;
  121. }
  122. // Include MooTools framework
  123. self::framework();
  124. JHtml::_('script', 'system/validate.js', true, true);
  125. self::$loaded[__METHOD__] = true;
  126. }
  127. /**
  128. * Add unobtrusive javascript support for submenu switcher support in
  129. * Global Configuration and System Information.
  130. *
  131. * @return void
  132. *
  133. * @since 11.1
  134. */
  135. public static function switcher()
  136. {
  137. // Only load once
  138. if (isset(self::$loaded[__METHOD__]))
  139. {
  140. return;
  141. }
  142. // Include MooTools framework
  143. self::framework();
  144. JHtml::_('script', 'system/switcher.js', true, true);
  145. $script = "
  146. document.switcher = null;
  147. window.addEvent('domready', function(){
  148. toggler = document.id('submenu');
  149. element = document.id('config-document');
  150. if (element) {
  151. document.switcher = new JSwitcher(toggler, element, {cookieName: toggler.getProperty('class')});
  152. }
  153. });";
  154. JFactory::getDocument()->addScriptDeclaration($script);
  155. self::$loaded[__METHOD__] = true;
  156. }
  157. /**
  158. * Add unobtrusive javascript support for a combobox effect.
  159. *
  160. * Note that this control is only reliable in absolutely positioned elements.
  161. * Avoid using a combobox in a slider or dynamic pane.
  162. *
  163. * @return void
  164. *
  165. * @since 11.1
  166. */
  167. public static function combobox()
  168. {
  169. if (isset(self::$loaded[__METHOD__]))
  170. {
  171. return;
  172. }
  173. // Include MooTools framework
  174. self::framework();
  175. JHtml::_('script', 'system/combobox.js', true, true);
  176. self::$loaded[__METHOD__] = true;
  177. }
  178. /**
  179. * Add unobtrusive javascript support for a hover tooltips.
  180. *
  181. * Add a title attribute to any element in the form
  182. * title="title::text"
  183. *
  184. *
  185. * Uses the core Tips class in MooTools.
  186. *
  187. * @param string $selector The class selector for the tooltip.
  188. * @param array $params An array of options for the tooltip.
  189. * Options for the tooltip can be:
  190. * - maxTitleChars integer The maximum number of characters in the tooltip title (defaults to 50).
  191. * - offsets object The distance of your tooltip from the mouse (defaults to {'x': 16, 'y': 16}).
  192. * - showDelay integer The millisecond delay the show event is fired (defaults to 100).
  193. * - hideDelay integer The millisecond delay the hide hide is fired (defaults to 100).
  194. * - className string The className your tooltip container will get.
  195. * - fixed boolean If set to true, the toolTip will not follow the mouse.
  196. * - onShow function The default function for the show event, passes the tip element
  197. * and the currently hovered element.
  198. * - onHide function The default function for the hide event, passes the currently
  199. * hovered element.
  200. *
  201. * @return void
  202. *
  203. * @since 11.1
  204. */
  205. public static function tooltip($selector = '.hasTip', $params = array())
  206. {
  207. $sig = md5(serialize(array($selector, $params)));
  208. if (isset(self::$loaded[__METHOD__][$sig]))
  209. {
  210. return;
  211. }
  212. // Include MooTools framework
  213. self::framework(true);
  214. // Setup options object
  215. $opt['maxTitleChars'] = (isset($params['maxTitleChars']) && ($params['maxTitleChars'])) ? (int) $params['maxTitleChars'] : 50;
  216. // offsets needs an array in the format: array('x'=>20, 'y'=>30)
  217. $opt['offset'] = (isset($params['offset']) && (is_array($params['offset']))) ? $params['offset'] : null;
  218. if (!isset($opt['offset']))
  219. {
  220. // Supporting offsets parameter which was working in mootools 1.2 (Joomla!1.5)
  221. $opt['offset'] = (isset($params['offsets']) && (is_array($params['offsets']))) ? $params['offsets'] : null;
  222. }
  223. $opt['showDelay'] = (isset($params['showDelay'])) ? (int) $params['showDelay'] : null;
  224. $opt['hideDelay'] = (isset($params['hideDelay'])) ? (int) $params['hideDelay'] : null;
  225. $opt['className'] = (isset($params['className'])) ? $params['className'] : null;
  226. $opt['fixed'] = (isset($params['fixed']) && ($params['fixed'])) ? true : false;
  227. $opt['onShow'] = (isset($params['onShow'])) ? '\\' . $params['onShow'] : null;
  228. $opt['onHide'] = (isset($params['onHide'])) ? '\\' . $params['onHide'] : null;
  229. $options = JHtmlBehavior::_getJSObject($opt);
  230. // Attach tooltips to document
  231. JFactory::getDocument()->addScriptDeclaration(
  232. "window.addEvent('domready', function() {
  233. $$('$selector').each(function(el) {
  234. var title = el.get('title');
  235. if (title) {
  236. var parts = title.split('::', 2);
  237. el.store('tip:title', parts[0]);
  238. el.store('tip:text', parts[1]);
  239. }
  240. });
  241. var JTooltips = new Tips($$('$selector'), $options);
  242. });"
  243. );
  244. // Set static array
  245. self::$loaded[__METHOD__][$sig] = true;
  246. return;
  247. }
  248. /**
  249. * Add unobtrusive javascript support for modal links.
  250. *
  251. * @param string $selector The selector for which a modal behaviour is to be applied.
  252. * @param array $params An array of parameters for the modal behaviour.
  253. * Options for the modal behaviour can be:
  254. * - ajaxOptions
  255. * - size
  256. * - shadow
  257. * - overlay
  258. * - onOpen
  259. * - onClose
  260. * - onUpdate
  261. * - onResize
  262. * - onShow
  263. * - onHide
  264. *
  265. * @return void
  266. *
  267. * @since 11.1
  268. */
  269. public static function modal($selector = 'a.modal', $params = array())
  270. {
  271. $document = JFactory::getDocument();
  272. // Load the necessary files if they haven't yet been loaded
  273. if (!isset(self::$loaded[__METHOD__]))
  274. {
  275. // Include MooTools framework
  276. self::framework();
  277. // Load the javascript and css
  278. JHtml::_('script', 'system/modal.js', true, true);
  279. JHtml::_('stylesheet', 'system/modal.css', array(), true);
  280. }
  281. $sig = md5(serialize(array($selector, $params)));
  282. if (isset(self::$loaded[__METHOD__][$sig]))
  283. {
  284. return;
  285. }
  286. // Setup options object
  287. $opt['ajaxOptions'] = (isset($params['ajaxOptions']) && (is_array($params['ajaxOptions']))) ? $params['ajaxOptions'] : null;
  288. $opt['handler'] = (isset($params['handler'])) ? $params['handler'] : null;
  289. $opt['fullScreen'] = (isset($params['fullScreen'])) ? (bool) $params['fullScreen'] : null;
  290. $opt['parseSecure'] = (isset($params['parseSecure'])) ? (bool) $params['parseSecure'] : null;
  291. $opt['closable'] = (isset($params['closable'])) ? (bool) $params['closable'] : null;
  292. $opt['closeBtn'] = (isset($params['closeBtn'])) ? (bool) $params['closeBtn'] : null;
  293. $opt['iframePreload'] = (isset($params['iframePreload'])) ? (bool) $params['iframePreload'] : null;
  294. $opt['iframeOptions'] = (isset($params['iframeOptions']) && (is_array($params['iframeOptions']))) ? $params['iframeOptions'] : null;
  295. $opt['size'] = (isset($params['size']) && (is_array($params['size']))) ? $params['size'] : null;
  296. $opt['shadow'] = (isset($params['shadow'])) ? $params['shadow'] : null;
  297. $opt['overlay'] = (isset($params['overlay'])) ? $params['overlay'] : null;
  298. $opt['onOpen'] = (isset($params['onOpen'])) ? $params['onOpen'] : null;
  299. $opt['onClose'] = (isset($params['onClose'])) ? $params['onClose'] : null;
  300. $opt['onUpdate'] = (isset($params['onUpdate'])) ? $params['onUpdate'] : null;
  301. $opt['onResize'] = (isset($params['onResize'])) ? $params['onResize'] : null;
  302. $opt['onMove'] = (isset($params['onMove'])) ? $params['onMove'] : null;
  303. $opt['onShow'] = (isset($params['onShow'])) ? $params['onShow'] : null;
  304. $opt['onHide'] = (isset($params['onHide'])) ? $params['onHide'] : null;
  305. $options = JHtmlBehavior::_getJSObject($opt);
  306. // Attach modal behavior to document
  307. $document
  308. ->addScriptDeclaration(
  309. "
  310. window.addEvent('domready', function() {
  311. SqueezeBox.initialize(" . $options . ");
  312. SqueezeBox.assign($$('" . $selector . "'), {
  313. parse: 'rel'
  314. });
  315. });"
  316. );
  317. // Set static array
  318. self::$loaded[__METHOD__][$sig] = true;
  319. return;
  320. }
  321. /**
  322. * JavaScript behavior to allow shift select in grids
  323. *
  324. * @param string $id The id of the form for which a multiselect behaviour is to be applied.
  325. *
  326. * @return void
  327. *
  328. * @since 11.1
  329. */
  330. public static function multiselect($id = 'adminForm')
  331. {
  332. // Only load once
  333. if (isset(self::$loaded[__METHOD__][$id]))
  334. {
  335. return;
  336. }
  337. // Include MooTools framework
  338. self::framework();
  339. JHtml::_('script', 'system/multiselect.js', true, true);
  340. // Attach multiselect to document
  341. JFactory::getDocument()->addScriptDeclaration(
  342. "window.addEvent('domready', function() {
  343. new Joomla.JMultiSelect('" . $id . "');
  344. });"
  345. );
  346. // Set static array
  347. self::$loaded[__METHOD__][$id] = true;
  348. return;
  349. }
  350. /**
  351. * Add unobtrusive javascript support for the advanced uploader.
  352. *
  353. * @param string $id An index.
  354. * @param array $params An array of options for the uploader.
  355. * @param string $upload_queue The HTML id of the upload queue element (??).
  356. *
  357. * @return void
  358. *
  359. * @since 11.1
  360. */
  361. public static function uploader($id = 'file-upload', $params = array(), $upload_queue = 'upload-queue')
  362. {
  363. // Include MooTools framework
  364. self::framework();
  365. JHtml::_('script', 'system/swf.js', true, true);
  366. JHtml::_('script', 'system/progressbar.js', true, true);
  367. JHtml::_('script', 'system/uploader.js', true, true);
  368. $document = JFactory::getDocument();
  369. if (!isset(self::$loaded[__METHOD__]))
  370. {
  371. JText::script('JLIB_HTML_BEHAVIOR_UPLOADER_FILENAME');
  372. JText::script('JLIB_HTML_BEHAVIOR_UPLOADER_UPLOAD_COMPLETED');
  373. JText::script('JLIB_HTML_BEHAVIOR_UPLOADER_ERROR_OCCURRED');
  374. JText::script('JLIB_HTML_BEHAVIOR_UPLOADER_ALL_FILES');
  375. JText::script('JLIB_HTML_BEHAVIOR_UPLOADER_PROGRESS_OVERALL');
  376. JText::script('JLIB_HTML_BEHAVIOR_UPLOADER_CURRENT_TITLE');
  377. JText::script('JLIB_HTML_BEHAVIOR_UPLOADER_REMOVE');
  378. JText::script('JLIB_HTML_BEHAVIOR_UPLOADER_REMOVE_TITLE');
  379. JText::script('JLIB_HTML_BEHAVIOR_UPLOADER_CURRENT_FILE');
  380. JText::script('JLIB_HTML_BEHAVIOR_UPLOADER_CURRENT_PROGRESS');
  381. JText::script('JLIB_HTML_BEHAVIOR_UPLOADER_FILE_ERROR');
  382. JText::script('JLIB_HTML_BEHAVIOR_UPLOADER_FILE_SUCCESSFULLY_UPLOADED');
  383. JText::script('JLIB_HTML_BEHAVIOR_UPLOADER_VALIDATION_ERROR_DUPLICATE');
  384. JText::script('JLIB_HTML_BEHAVIOR_UPLOADER_VALIDATION_ERROR_SIZELIMITMIN');
  385. JText::script('JLIB_HTML_BEHAVIOR_UPLOADER_VALIDATION_ERROR_SIZELIMITMAX');
  386. JText::script('JLIB_HTML_BEHAVIOR_UPLOADER_VALIDATION_ERROR_FILELISTMAX');
  387. JText::script('JLIB_HTML_BEHAVIOR_UPLOADER_VALIDATION_ERROR_FILELISTSIZEMAX');
  388. JText::script('JLIB_HTML_BEHAVIOR_UPLOADER_ERROR_HTTPSTATUS');
  389. JText::script('JLIB_HTML_BEHAVIOR_UPLOADER_ERROR_SECURITYERROR');
  390. JText::script('JLIB_HTML_BEHAVIOR_UPLOADER_ERROR_IOERROR');
  391. JText::script('JLIB_HTML_BEHAVIOR_UPLOADER_ALL_FILES');
  392. }
  393. if (isset(self::$loaded[__METHOD__][$id]))
  394. {
  395. return;
  396. }
  397. $onFileSuccess = '\\function(file, response) {
  398. var json = new Hash(JSON.decode(response, true) || {});
  399. if (json.get(\'status\') == \'1\') {
  400. file.element.addClass(\'file-success\');
  401. file.info.set(\'html\', \'<strong>\' + Joomla.JText._(\'JLIB_HTML_BEHAVIOR_UPLOADER_FILE_SUCCESSFULLY_UPLOADED\') + \'</strong>\');
  402. } else {
  403. file.element.addClass(\'file-failed\');
  404. file.info.set(\'html\', \'<strong>\' +
  405. Joomla.JText._(\'JLIB_HTML_BEHAVIOR_UPLOADER_ERROR_OCCURRED\',
  406. \'An Error Occurred\').substitute({ error: json.get(\'error\') }) + \'</strong>\');
  407. }
  408. }';
  409. // Setup options object
  410. $opt['verbose'] = true;
  411. $opt['url'] = (isset($params['targetURL'])) ? $params['targetURL'] : null;
  412. $opt['path'] = (isset($params['swf'])) ? $params['swf'] : JURI::root(true) . '/media/system/swf/uploader.swf';
  413. $opt['height'] = (isset($params['height'])) && $params['height'] ? (int) $params['height'] : null;
  414. $opt['width'] = (isset($params['width'])) && $params['width'] ? (int) $params['width'] : null;
  415. $opt['multiple'] = (isset($params['multiple']) && !($params['multiple'])) ? false : true;
  416. $opt['queued'] = (isset($params['queued']) && !($params['queued'])) ? (int) $params['queued'] : null;
  417. $opt['target'] = (isset($params['target'])) ? $params['target'] : '\\document.id(\'upload-browse\')';
  418. $opt['instantStart'] = (isset($params['instantStart']) && ($params['instantStart'])) ? true : false;
  419. $opt['allowDuplicates'] = (isset($params['allowDuplicates']) && !($params['allowDuplicates'])) ? false : true;
  420. // limitSize is the old parameter name. Remove in 1.7
  421. $opt['fileSizeMax'] = (isset($params['limitSize']) && ($params['limitSize'])) ? (int) $params['limitSize'] : null;
  422. // fileSizeMax is the new name. If supplied, it will override the old value specified for limitSize
  423. $opt['fileSizeMax'] = (isset($params['fileSizeMax']) && ($params['fileSizeMax'])) ? (int) $params['fileSizeMax'] : $opt['fileSizeMax'];
  424. $opt['fileSizeMin'] = (isset($params['fileSizeMin']) && ($params['fileSizeMin'])) ? (int) $params['fileSizeMin'] : null;
  425. // limitFiles is the old parameter name. Remove in 1.7
  426. $opt['fileListMax'] = (isset($params['limitFiles']) && ($params['limitFiles'])) ? (int) $params['limitFiles'] : null;
  427. // fileListMax is the new name. If supplied, it will override the old value specified for limitFiles
  428. $opt['fileListMax'] = (isset($params['fileListMax']) && ($params['fileListMax'])) ? (int) $params['fileListMax'] : $opt['fileListMax'];
  429. $opt['fileListSizeMax'] = (isset($params['fileListSizeMax']) && ($params['fileListSizeMax'])) ? (int) $params['fileListSizeMax'] : null;
  430. // types is the old parameter name. Remove in 1.7
  431. $opt['typeFilter'] = (isset($params['types'])) ? '\\' . $params['types']
  432. : '\\{Joomla.JText._(\'JLIB_HTML_BEHAVIOR_UPLOADER_ALL_FILES\'): \'*.*\'}';
  433. $opt['typeFilter'] = (isset($params['typeFilter'])) ? '\\' . $params['typeFilter'] : $opt['typeFilter'];
  434. // Optional functions
  435. $opt['createReplacement'] = (isset($params['createReplacement'])) ? '\\' . $params['createReplacement'] : null;
  436. $opt['onFileComplete'] = (isset($params['onFileComplete'])) ? '\\' . $params['onFileComplete'] : null;
  437. $opt['onBeforeStart'] = (isset($params['onBeforeStart'])) ? '\\' . $params['onBeforeStart'] : null;
  438. $opt['onStart'] = (isset($params['onStart'])) ? '\\' . $params['onStart'] : null;
  439. $opt['onComplete'] = (isset($params['onComplete'])) ? '\\' . $params['onComplete'] : null;
  440. $opt['onFileSuccess'] = (isset($params['onFileSuccess'])) ? '\\' . $params['onFileSuccess'] : $onFileSuccess;
  441. if (!isset($params['startButton']))
  442. {
  443. $params['startButton'] = 'upload-start';
  444. }
  445. if (!isset($params['clearButton']))
  446. {
  447. $params['clearButton'] = 'upload-clear';
  448. }
  449. $opt['onLoad'] = '\\function() {
  450. document.id(\'' . $id
  451. . '\').removeClass(\'hide\'); // we show the actual UI
  452. document.id(\'upload-noflash\').destroy(); // ... and hide the plain form
  453. // We relay the interactions with the overlayed flash to the link
  454. this.target.addEvents({
  455. click: function() {
  456. return false;
  457. },
  458. mouseenter: function() {
  459. this.addClass(\'hover\');
  460. },
  461. mouseleave: function() {
  462. this.removeClass(\'hover\');
  463. this.blur();
  464. },
  465. mousedown: function() {
  466. this.focus();
  467. }
  468. });
  469. // Interactions for the 2 other buttons
  470. document.id(\'' . $params['clearButton']
  471. . '\').addEvent(\'click\', function() {
  472. Uploader.remove(); // remove all files
  473. return false;
  474. });
  475. document.id(\'' . $params['startButton']
  476. . '\').addEvent(\'click\', function() {
  477. Uploader.start(); // start upload
  478. return false;
  479. });
  480. }';
  481. $options = JHtmlBehavior::_getJSObject($opt);
  482. // Attach tooltips to document
  483. $uploaderInit = 'window.addEvent(\'domready\', function(){
  484. var Uploader = new FancyUpload2(document.id(\'' . $id . '\'), document.id(\'' . $upload_queue . '\'), ' . $options . ' );
  485. });';
  486. $document->addScriptDeclaration($uploaderInit);
  487. // Set static array
  488. self::$loaded[__METHOD__][$id] = true;
  489. return;
  490. }
  491. /**
  492. * Add unobtrusive javascript support for a collapsible tree.
  493. *
  494. * @param string $id An index
  495. * @param array $params An array of options.
  496. * @param array $root The root node
  497. *
  498. * @return void
  499. *
  500. * @since 11.1
  501. */
  502. public static function tree($id, $params = array(), $root = array())
  503. {
  504. // Include MooTools framework
  505. self::framework();
  506. JHtml::_('script', 'system/mootree.js', true, true, false, false);
  507. JHtml::_('stylesheet', 'system/mootree.css', array(), true);
  508. if (isset(self::$loaded[__METHOD__][$id]))
  509. {
  510. return;
  511. }
  512. // Setup options object
  513. $opt['div'] = (array_key_exists('div', $params)) ? $params['div'] : $id . '_tree';
  514. $opt['mode'] = (array_key_exists('mode', $params)) ? $params['mode'] : 'folders';
  515. $opt['grid'] = (array_key_exists('grid', $params)) ? '\\' . $params['grid'] : true;
  516. $opt['theme'] = (array_key_exists('theme', $params)) ? $params['theme'] : JHtml::_('image', 'system/mootree.gif', '', array(), true, true);
  517. // Event handlers
  518. $opt['onExpand'] = (array_key_exists('onExpand', $params)) ? '\\' . $params['onExpand'] : null;
  519. $opt['onSelect'] = (array_key_exists('onSelect', $params)) ? '\\' . $params['onSelect'] : null;
  520. $opt['onClick'] = (array_key_exists('onClick', $params)) ? '\\' . $params['onClick']
  521. : '\\function(node){ window.open(node.data.url, node.data.target != null ? node.data.target : \'_self\'); }';
  522. $options = JHtmlBehavior::_getJSObject($opt);
  523. // Setup root node
  524. $rt['text'] = (array_key_exists('text', $root)) ? $root['text'] : 'Root';
  525. $rt['id'] = (array_key_exists('id', $root)) ? $root['id'] : null;
  526. $rt['color'] = (array_key_exists('color', $root)) ? $root['color'] : null;
  527. $rt['open'] = (array_key_exists('open', $root)) ? '\\' . $root['open'] : true;
  528. $rt['icon'] = (array_key_exists('icon', $root)) ? $root['icon'] : null;
  529. $rt['openicon'] = (array_key_exists('openicon', $root)) ? $root['openicon'] : null;
  530. $rt['data'] = (array_key_exists('data', $root)) ? $root['data'] : null;
  531. $rootNode = JHtmlBehavior::_getJSObject($rt);
  532. $treeName = (array_key_exists('treeName', $params)) ? $params['treeName'] : '';
  533. $js = ' window.addEvent(\'domready\', function(){
  534. tree' . $treeName . ' = new MooTreeControl(' . $options . ',' . $rootNode . ');
  535. tree' . $treeName . '.adopt(\'' . $id . '\');})';
  536. // Attach tooltips to document
  537. $document = JFactory::getDocument();
  538. $document->addScriptDeclaration($js);
  539. // Set static array
  540. self::$loaded[__METHOD__][$id] = true;
  541. return;
  542. }
  543. /**
  544. * Add unobtrusive javascript support for a calendar control.
  545. *
  546. * @return void
  547. *
  548. * @since 11.1
  549. */
  550. public static function calendar()
  551. {
  552. // Only load once
  553. if (isset(self::$loaded[__METHOD__]))
  554. {
  555. return;
  556. }
  557. $document = JFactory::getDocument();
  558. $tag = JFactory::getLanguage()->getTag();
  559. JHtml::_('stylesheet', 'system/calendar-jos.css', array(' title' => JText::_('JLIB_HTML_BEHAVIOR_GREEN'), ' media' => 'all'), true);
  560. JHtml::_('script', $tag . '/calendar.js', false, true);
  561. JHtml::_('script', $tag . '/calendar-setup.js', false, true);
  562. $translation = JHtmlBehavior::_calendartranslation();
  563. if ($translation)
  564. {
  565. $document->addScriptDeclaration($translation);
  566. }
  567. self::$loaded[__METHOD__] = true;
  568. }
  569. /**
  570. * Add unobtrusive javascript support for a color picker.
  571. *
  572. * @return void
  573. *
  574. * @since 11.2
  575. */
  576. public static function colorpicker()
  577. {
  578. // Only load once
  579. if (isset(self::$loaded[__METHOD__]))
  580. {
  581. return;
  582. }
  583. // Include MooTools framework
  584. self::framework(true);
  585. JHtml::_('stylesheet', 'system/mooRainbow.css', array('media' => 'all'), true);
  586. JHtml::_('script', 'system/mooRainbow.js', false, true);
  587. JFactory::getDocument()
  588. ->addScriptDeclaration(
  589. "window.addEvent('domready', function(){
  590. var nativeColorUi = false;
  591. if (Browser.opera && (Browser.version >= 11.5)) {
  592. nativeColorUi = true;
  593. }
  594. $$('.input-colorpicker').each(function(item){
  595. if (nativeColorUi) {
  596. item.type = 'color';
  597. } else {
  598. new MooRainbow(item, {
  599. id: item.id,
  600. imgPath: '" . JURI::root(true) . "/media/system/images/mooRainbow/',
  601. onComplete: function(color) {
  602. this.element.value = color.hex;
  603. },
  604. startColor: item.value.hexToRgb(true) ? item.value.hexToRgb(true) : [0, 0, 0]
  605. });
  606. }
  607. });
  608. });
  609. ");
  610. self::$loaded[__METHOD__] = true;
  611. }
  612. /**
  613. * Keep session alive, for example, while editing or creating an article.
  614. *
  615. * @return void
  616. *
  617. * @since 11.1
  618. */
  619. public static function keepalive()
  620. {
  621. // Only load once
  622. if (isset(self::$loaded[__METHOD__]))
  623. {
  624. return;
  625. }
  626. // Include MooTools framework
  627. self::framework();
  628. $config = JFactory::getConfig();
  629. $lifetime = ($config->get('lifetime') * 60000);
  630. $refreshTime = ($lifetime <= 60000) ? 30000 : $lifetime - 60000;
  631. // Refresh time is 1 minute less than the liftime assined in the configuration.php file.
  632. // the longest refresh period is one hour to prevent integer overflow.
  633. if ($refreshTime > 3600000 || $refreshTime <= 0)
  634. {
  635. $refreshTime = 3600000;
  636. }
  637. $document = JFactory::getDocument();
  638. $script = '';
  639. $script .= 'function keepAlive() {';
  640. $script .= ' var myAjax = new Request({method: "get", url: "index.php"}).send();';
  641. $script .= '}';
  642. $script .= ' window.addEvent("domready", function()';
  643. $script .= '{ keepAlive.periodical(' . $refreshTime . '); }';
  644. $script .= ');';
  645. $document->addScriptDeclaration($script);
  646. self::$loaded[__METHOD__] = true;
  647. return;
  648. }
  649. /**
  650. * Highlight some words via Javascript.
  651. *
  652. * @param array $terms Array of words that should be highlighted.
  653. * @param string $start ID of the element that marks the begin of the section in which words
  654. * should be highlighted. Note this element will be removed from the DOM.
  655. * @param string $end ID of the element that end this section.
  656. * Note this element will be removed from the DOM.
  657. * @param string $className Class name of the element highlights are wrapped in.
  658. * @param string $tag Tag that will be used to wrap the highlighted words.
  659. *
  660. * @return void
  661. *
  662. * @since 11.4
  663. */
  664. public static function highlighter(array $terms, $start = 'highlighter-start', $end = 'highlighter-end', $className = 'highlight', $tag = 'span')
  665. {
  666. $sig = md5(serialize(array($terms, $start, $end)));
  667. if (isset(self::$loaded[__METHOD__][$sig]))
  668. {
  669. return;
  670. }
  671. JHtml::_('script', 'system/highlighter.js', true, true);
  672. $terms = str_replace('"', '\"', $terms);
  673. $document = JFactory::getDocument();
  674. $document->addScriptDeclaration("
  675. window.addEvent('domready', function () {
  676. var start = document.id('" . $start . "');
  677. var end = document.id('" . $end . "');
  678. if (!start || !end || !Joomla.Highlighter) {
  679. return true;
  680. }
  681. highlighter = new Joomla.Highlighter({
  682. startElement: start,
  683. endElement: end,
  684. className: '" . $className . "',
  685. onlyWords: false,
  686. tag: '" . $tag . "'
  687. }).highlight([\"" . implode('","', $terms) . "\"]);
  688. start.dispose();
  689. end.dispose();
  690. });
  691. ");
  692. self::$loaded[__METHOD__][$sig] = true;
  693. return;
  694. }
  695. /**
  696. * Break us out of any containing iframes
  697. *
  698. * @param string $location Location to display in
  699. *
  700. * @return void
  701. *
  702. * @since 11.1
  703. */
  704. public static function noframes($location = 'top.location.href')
  705. {
  706. // Only load once
  707. if (isset(self::$loaded[__METHOD__]))
  708. {
  709. return;
  710. }
  711. // Include MooTools framework
  712. self::framework();
  713. $js = "window.addEvent('domready', function () {if (top == self) {document.documentElement.style.display = 'block'; }" .
  714. " else {top.location = self.location; }});";
  715. $document = JFactory::getDocument();
  716. $document->addStyleDeclaration('html { display:none }');
  717. $document->addScriptDeclaration($js);
  718. JResponse::setHeader('X-Frames-Options', 'SAME-ORIGIN');
  719. self::$loaded[__METHOD__] = true;
  720. }
  721. /**
  722. * Internal method to get a JavaScript object notation string from an array
  723. *
  724. * @param array $array The array to convert to JavaScript object notation
  725. *
  726. * @return string JavaScript object notation representation of the array
  727. *
  728. * @since 11.1
  729. */
  730. protected static function _getJSObject($array = array())
  731. {
  732. // Initialise variables.
  733. $object = '{';
  734. // Iterate over array to build objects
  735. foreach ((array) $array as $k => $v)
  736. {
  737. if (is_null($v))
  738. {
  739. continue;
  740. }
  741. if (is_bool($v))
  742. {
  743. if ($k === 'fullScreen')
  744. {
  745. $object .= 'size: { ';
  746. $object .= 'x: ';
  747. $object .= 'window.getSize().x-80';
  748. $object .= ',';
  749. $object .= 'y: ';
  750. $object .= 'window.getSize().y-80';
  751. $object .= ' }';
  752. $object .= ',';
  753. }
  754. else
  755. {
  756. $object .= ' ' . $k . ': ';
  757. $object .= ($v) ? 'true' : 'false';
  758. $object .= ',';
  759. }
  760. }
  761. elseif (!is_array($v) && !is_object($v))
  762. {
  763. $object .= ' ' . $k . ': ';
  764. $object .= (is_numeric($v) || strpos($v, '\\') === 0) ? (is_numeric($v)) ? $v : substr($v, 1) : "'" . $v . "'";
  765. $object .= ',';
  766. }
  767. else
  768. {
  769. $object .= ' ' . $k . ': ' . JHtmlBehavior::_getJSObject($v) . ',';
  770. }
  771. }
  772. if (substr($object, -1) == ',')
  773. {
  774. $object = substr($object, 0, -1);
  775. }
  776. $object .= '}';
  777. return $object;
  778. }
  779. /**
  780. * Internal method to translate the JavaScript Calendar
  781. *
  782. * @return string JavaScript that translates the object
  783. *
  784. * @since 11.1
  785. */
  786. protected static function _calendartranslation()
  787. {
  788. static $jsscript = 0;
  789. if ($jsscript == 0)
  790. {
  791. $return = 'Calendar._DN = new Array ("' . JText::_('SUNDAY', true) . '", "' . JText::_('MONDAY', true) . '", "'
  792. . JText::_('TUESDAY', true) . '", "' . JText::_('WEDNESDAY', true) . '", "' . JText::_('THURSDAY', true) . '", "'
  793. . JText::_('FRIDAY', true) . '", "' . JText::_('SATURDAY', true) . '", "' . JText::_('SUNDAY', true) . '");'
  794. . ' Calendar._SDN = new Array ("' . JText::_('SUN', true) . '", "' . JText::_('MON', true) . '", "' . JText::_('TUE', true) . '", "'
  795. . JText::_('WED', true) . '", "' . JText::_('THU', true) . '", "' . JText::_('FRI', true) . '", "' . JText::_('SAT', true) . '", "'
  796. . JText::_('SUN', true) . '");' . ' Calendar._FD = 0;' . ' Calendar._MN = new Array ("' . JText::_('JANUARY', true) . '", "'
  797. . JText::_('FEBRUARY', true) . '", "' . JText::_('MARCH', true) . '", "' . JText::_('APRIL', true) . '", "' . JText::_('MAY', true)
  798. . '", "' . JText::_('JUNE', true) . '", "' . JText::_('JULY', true) . '", "' . JText::_('AUGUST', true) . '", "'
  799. . JText::_('SEPTEMBER', true) . '", "' . JText::_('OCTOBER', true) . '", "' . JText::_('NOVEMBER', true) . '", "'
  800. . JText::_('DECEMBER', true) . '");' . ' Calendar._SMN = new Array ("' . JText::_('JANUARY_SHORT', true) . '", "'
  801. . JText::_('FEBRUARY_SHORT', true) . '", "' . JText::_('MARCH_SHORT', true) . '", "' . JText::_('APRIL_SHORT', true) . '", "'
  802. . JText::_('MAY_SHORT', true) . '", "' . JText::_('JUNE_SHORT', true) . '", "' . JText::_('JULY_SHORT', true) . '", "'
  803. . JText::_('AUGUST_SHORT', true) . '", "' . JText::_('SEPTEMBER_SHORT', true) . '", "' . JText::_('OCTOBER_SHORT', true) . '", "'
  804. . JText::_('NOVEMBER_SHORT', true) . '", "' . JText::_('DECEMBER_SHORT', true) . '");'
  805. . ' Calendar._TT = {};Calendar._TT["INFO"] = "' . JText::_('JLIB_HTML_BEHAVIOR_ABOUT_THE_CALENDAR', true) . '";'
  806. . ' Calendar._TT["ABOUT"] =
  807. "DHTML Date/Time Selector\n" +
  808. "(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" +
  809. "For latest version visit: http://www.dynarch.com/projects/calendar/\n" +
  810. "Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." +
  811. "\n\n" +
  812. "' . JText::_('JLIB_HTML_BEHAVIOR_DATE_SELECTION', false, false) . '" +
  813. "' . JText::_('JLIB_HTML_BEHAVIOR_YEAR_SELECT', false, false) . '" +
  814. "' . JText::_('JLIB_HTML_BEHAVIOR_MONTH_SELECT', false, false) . '" +
  815. "' . JText::_('JLIB_HTML_BEHAVIOR_HOLD_MOUSE', false, false)
  816. . '";
  817. Calendar._TT["ABOUT_TIME"] = "\n\n" +
  818. "Time selection:\n" +
  819. "- Click on any of the time parts to increase it\n" +
  820. "- or Shift-click to decrease it\n" +
  821. "- or click and drag for faster selection.";
  822. Calendar._TT["PREV_YEAR"] = "' . JText::_('JLIB_HTML_BEHAVIOR_PREV_YEAR_HOLD_FOR_MENU', true) . '";' . ' Calendar._TT["PREV_MONTH"] = "'
  823. . JText::_('JLIB_HTML_BEHAVIOR_PREV_MONTH_HOLD_FOR_MENU', true) . '";' . ' Calendar._TT["GO_TODAY"] = "'
  824. . JText::_('JLIB_HTML_BEHAVIOR_GO_TODAY', true) . '";' . ' Calendar._TT["NEXT_MONTH"] = "'
  825. . JText::_('JLIB_HTML_BEHAVIOR_NEXT_MONTH_HOLD_FOR_MENU', true) . '";' . ' Calendar._TT["NEXT_YEAR"] = "'
  826. . JText::_('JLIB_HTML_BEHAVIOR_NEXT_YEAR_HOLD_FOR_MENU', true) . '";' . ' Calendar._TT["SEL_DATE"] = "'
  827. . JText::_('JLIB_HTML_BEHAVIOR_SELECT_DATE', true) . '";' . ' Calendar._TT["DRAG_TO_MOVE"] = "'
  828. . JText::_('JLIB_HTML_BEHAVIOR_DRAG_TO_MOVE', true) . '";' . ' Calendar._TT["PART_TODAY"] = "'
  829. . JText::_('JLIB_HTML_BEHAVIOR_TODAY', true) . '";' . ' Calendar._TT["DAY_FIRST"] = "'
  830. . JText::_('JLIB_HTML_BEHAVIOR_DISPLAY_S_FIRST', true) . '";' . ' Calendar._TT["WEEKEND"] = "0,6";' . ' Calendar._TT["CLOSE"] = "'
  831. . JText::_('JLIB_HTML_BEHAVIOR_CLOSE', true) . '";' . ' Calendar._TT["TODAY"] = "' . JText::_('JLIB_HTML_BEHAVIOR_TODAY', true)
  832. . '";' . ' Calendar._TT["TIME_PART"] = "' . JText::_('JLIB_HTML_BEHAVIOR_SHIFT_CLICK_OR_DRAG_TO_CHANGE_VALUE', true) . '";'
  833. . ' Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d";' . ' Calendar._TT["TT_DATE_FORMAT"] = "'
  834. . JText::_('JLIB_HTML_BEHAVIOR_TT_DATE_FORMAT', true) . '";' . ' Calendar._TT["WK"] = "' . JText::_('JLIB_HTML_BEHAVIOR_WK', true) . '";'
  835. . ' Calendar._TT["TIME"] = "' . JText::_('JLIB_HTML_BEHAVIOR_TIME', true) . '";';
  836. $jsscript = 1;
  837. return $return;
  838. }
  839. else
  840. {
  841. return false;
  842. }
  843. }
  844. }