PageRenderTime 51ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/cake/libs/view/helpers/js.php

https://github.com/msadouni/cakephp2x
PHP | 1061 lines | 569 code | 54 blank | 438 comment | 88 complexity | bc9a2bc6fce9ffdb3e3a317f231fabcf MD5 | raw file
  1. <?php
  2. /**
  3. * Javascript Generator class file.
  4. *
  5. * PHP Version 5.x
  6. *
  7. * CakePHP : Rapid Development Framework (http://cakephp.org)
  8. * Copyright 2006-2009, Cake Software Foundation, Inc.
  9. *
  10. * Licensed under The MIT License
  11. * Redistributions of files must retain the above copyright notice.
  12. *
  13. * @copyright Copyright 2006-2009, Cake Software Foundation, Inc.
  14. * @link http://cakephp.org CakePHP Project
  15. * @package cake
  16. * @subpackage cake.cake.libs.view.helpers
  17. * @since CakePHP v 1.2
  18. * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
  19. */
  20. /**
  21. * Javascript Generator helper class for easy use of JavaScript.
  22. *
  23. * JsHelper provides an abstract interface for authoring JavaScript with a
  24. * given client-side library.
  25. *
  26. * @package cake
  27. * @subpackage cake.cake.libs.view.helpers
  28. */
  29. class JsHelper extends AppHelper {
  30. /**
  31. * Whether or not you want scripts to be buffered or output.
  32. *
  33. * @var boolean
  34. */
  35. public $bufferScripts = true;
  36. /**
  37. * helpers
  38. *
  39. * @var array
  40. */
  41. public $helpers = array('Html', 'Form');
  42. /**
  43. * Variables to pass to Javascript.
  44. *
  45. * @var array
  46. * @see JsHelper::set()
  47. */
  48. private $__jsVars = array();
  49. /**
  50. * Scripts that are queued for output
  51. *
  52. * @var array
  53. */
  54. private $__bufferedScripts = array();
  55. /**
  56. * Current Javascript Engine that is being used
  57. *
  58. * @var string
  59. * @access private
  60. */
  61. private $__engineName;
  62. /**
  63. * The javascript variable created by set() variables.
  64. *
  65. * @var string
  66. */
  67. public $setVariable = APP_DIR;
  68. /**
  69. * Constructor - determines engine helper
  70. *
  71. * @param array $settings Settings array contains name of engine helper.
  72. * @access public
  73. * @return void
  74. */
  75. public function __construct($settings = array()) {
  76. $className = 'Jquery';
  77. if (is_array($settings) && isset($settings[0])) {
  78. $className = $settings[0];
  79. } elseif (is_string($settings)) {
  80. $className = $settings;
  81. }
  82. $engineName = $className;
  83. list($plugin, $className) = pluginSplit($className);
  84. $this->__engineName = $className . 'Engine';
  85. $engineClass = $engineName . 'Engine';
  86. $this->helpers[] = $engineClass;
  87. parent::__construct();
  88. }
  89. /**
  90. * call__ Allows for dispatching of methods to the Engine Helper.
  91. * methods in the Engines bufferedMethods list will be automatically buffered.
  92. * You can control buffering with the buffer param as well. By setting the last parameter to
  93. * any engine method to a boolean you can force or disable buffering.
  94. *
  95. * e.g. `$js->get('#foo')->effect('fadeIn', array('speed' => 'slow'), true);`
  96. *
  97. * Will force buffering for the effect method. If the method takes an options array you may also add
  98. * a 'buffer' param to the options array and control buffering there as well.
  99. *
  100. * e.g. `$js->get('#foo')->event('click', $functionContents, array('buffer' => true));`
  101. *
  102. * The buffer parameter will not be passed onto the EngineHelper.
  103. *
  104. * @param string $method Method to be called
  105. * @param array $params Parameters for the method being called.
  106. * @access public
  107. * @return mixed Depends on the return of the dispatched method, or it could be an instance of the EngineHelper
  108. */
  109. public function call__($method, $params) {
  110. if (isset($this->{$this->__engineName}) && method_exists($this->{$this->__engineName}, $method)) {
  111. $buffer = false;
  112. if (in_array(strtolower($method), $this->{$this->__engineName}->bufferedMethods)) {
  113. $buffer = true;
  114. }
  115. if (count($params) > 0) {
  116. $lastParam = $params[count($params) - 1];
  117. $hasBufferParam = (is_bool($lastParam) || is_array($lastParam) && isset($lastParam['buffer']));
  118. if ($hasBufferParam && is_bool($lastParam)) {
  119. $buffer = $lastParam;
  120. unset($params[count($params) - 1]);
  121. } elseif ($hasBufferParam && is_array($lastParam)) {
  122. $buffer = $lastParam['buffer'];
  123. unset($params['buffer']);
  124. }
  125. }
  126. $out = $this->{$this->__engineName}->dispatchMethod($method, $params);
  127. if ($this->bufferScripts && $buffer && is_string($out)) {
  128. $this->buffer($out);
  129. return null;
  130. }
  131. if (is_object($out) && is_a($out, 'JsBaseEngineHelper')) {
  132. return $this;
  133. }
  134. return $out;
  135. }
  136. if (method_exists($this, $method . '_')) {
  137. return $this->dispatchMethod($method . '_', $params);
  138. }
  139. trigger_error(sprintf(__('JsHelper:: Missing Method %s is undefined', true), $method), E_USER_WARNING);
  140. }
  141. /**
  142. * Workaround for Object::Object() existing. Since Object::object exists, it does not
  143. * fall into call__ and is not passed onto the engine helper. See JsBaseEngineHelper::object() for
  144. * more information on this method.
  145. *
  146. * @param mixed $data Data to convert into JSON
  147. * @param array $options Options to use for encoding JSON. See JsBaseEngineHelper::object() for more details.
  148. * @return string encoded JSON
  149. * @deprecated Remove when support for PHP4 and Object::object are removed.
  150. */
  151. public function object($data = array(), $options = array()) {
  152. return $this->{$this->__engineName}->object($data, $options);
  153. }
  154. /**
  155. * Overwrite inherited Helper::value()
  156. * See JsBaseEngineHelper::value() for more information on this method.
  157. *
  158. * @param mixed $val A PHP variable to be converted to JSON
  159. * @param boolean $quoteStrings If false, leaves string values unquoted
  160. * @return string a JavaScript-safe/JSON representation of $val
  161. * @access public
  162. **/
  163. function value($val, $quoteString = true) {
  164. return $this->{$this->__engineName}->value($val, $quoteString);
  165. }
  166. /**
  167. * Writes all Javascript generated so far to a code block or
  168. * caches them to a file and returns a linked script.
  169. *
  170. * Options
  171. *
  172. * - `inline` - Set to true to have scripts output as a script block inline
  173. * if `cache` is also true, a script link tag will be generated. (default true)
  174. * - `cache` - Set to true to have scripts cached to a file and linked in (default false)
  175. * - `clear` - Set to false to prevent script cache from being cleared (default true)
  176. * - `onDomReady` - wrap cached scripts in domready event (default true)
  177. * - `safe` - if an inline block is generated should it be wrapped in <![CDATA[ ... ]]> (default true)
  178. *
  179. * @param array $options options for the code block
  180. * @return string completed javascript tag.
  181. */
  182. public function writeBuffer($options = array()) {
  183. $defaults = array('onDomReady' => true, 'inline' => true, 'cache' => false, 'clear' => true, 'safe' => true);
  184. $options = array_merge($defaults, $options);
  185. $script = implode("\n", $this->getBuffer($options['clear']));
  186. if ($options['onDomReady']) {
  187. $script = $this->{$this->__engineName}->domReady($script);
  188. }
  189. if (!$options['cache'] && $options['inline']) {
  190. $opts = $options;
  191. unset($opts['onDomReady'], $opts['cache'], $opts['clear']);
  192. return $this->Html->scriptBlock($script, $opts);
  193. }
  194. if ($options['cache'] && $options['inline']) {
  195. $filename = md5($script);
  196. if (!file_exists(JS . $filename . '.js')) {
  197. cache(str_replace(WWW_ROOT, '', JS) . $filename . '.js', $script, '+999 days', 'public');
  198. }
  199. return $this->Html->script($filename);
  200. }
  201. $view =& ClassRegistry::getObject('view');
  202. $view->addScript($script);
  203. return null;
  204. }
  205. /**
  206. * Write a script to the cached scripts.
  207. *
  208. * @return void
  209. */
  210. public function buffer($script) {
  211. $this->__bufferedScripts[] = $script;
  212. }
  213. /**
  214. * Get all the cached scripts
  215. *
  216. * @param boolean $clear Whether or not to clear the script caches (default true)
  217. * @return array Array of scripts added to the request.
  218. */
  219. function getBuffer($clear = true) {
  220. $this->_createVars();
  221. $scripts = $this->__bufferedScripts;
  222. if ($clear) {
  223. $this->__bufferedScripts = array();
  224. $this->__jsVars = array();
  225. }
  226. return $scripts;
  227. }
  228. /**
  229. * Generates the object string for variables passed to javascript.
  230. *
  231. * @return string
  232. * @access protected
  233. */
  234. protected function _createVars() {
  235. if (!empty($this->__jsVars)) {
  236. $setVar = (strpos($this->setVariable, '.')) ? $this->setVariable : 'var ' . $this->setVariable;
  237. $this->buffer($setVar . ' = ' . $this->object($this->__jsVars) . ';');
  238. }
  239. }
  240. /**
  241. * Generate an 'Ajax' link. Uses the selected JS engine to create a link
  242. * element that is enhanced with Javascript. Options can include
  243. * both those for HtmlHelper::link() and JsBaseEngine::request(), JsBaseEngine::event();
  244. *
  245. * ### Options
  246. *
  247. * - `confirm` - Generate a confirm() dialog before sending the event.
  248. * - `id` - use a custom id.
  249. * - `htmlAttributes` - additional non-standard htmlAttributes. Standard attributes are class, id,
  250. * rel, title, escape, onblur and onfocus.
  251. * - `buffer` - Disable the buffering and return a script tag in addition to the link.
  252. *
  253. * @param string $title Title for the link.
  254. * @param mixed $url Mixed either a string URL or an cake url array.
  255. * @param array $options Options for both the HTML element and Js::request()
  256. * @return string Completed link. If buffering is disabled a script tag will be returned as well.
  257. */
  258. public function link($title, $url = null, $options = array()) {
  259. if (!isset($options['id'])) {
  260. $options['id'] = 'link-' . intval(mt_rand());
  261. }
  262. $htmlOptions = $this->_getHtmlOptions($options);
  263. $out = $this->Html->link($title, $url, $htmlOptions);
  264. $this->get('#' . $htmlOptions['id']);
  265. $requestString = '';
  266. if (isset($options['confirm'])) {
  267. $requestString = $this->confirmReturn($options['confirm']);
  268. unset($options['confirm']);
  269. }
  270. $requestString .= $this->request($url, $options);
  271. if (!empty($requestString)) {
  272. $event = $this->event('click', $requestString, $options);
  273. }
  274. if (isset($options['buffer']) && $options['buffer'] == false) {
  275. $opts = array();
  276. if (isset($options['safe'])) {
  277. $opts['safe'] = $options['safe'];
  278. }
  279. $out .= $this->Html->scriptBlock($event, $opts);
  280. }
  281. return $out;
  282. }
  283. /**
  284. * Pass variables into Javascript. Allows you to set variables that will be
  285. * output when the buffer is fetched with `JsHelper::getBuffer()` or `JsHelper::writeBuffer()`
  286. * The Javascript variable used to output set variables can be controlled with `JsHelper::$setVariable`
  287. *
  288. * @param mixed $one
  289. * @param mixed $two
  290. * @return void
  291. * @access protected
  292. */
  293. protected function set($one, $two = null) {
  294. $data = null;
  295. if (is_array($one)) {
  296. if (is_array($two)) {
  297. $data = array_combine($one, $two);
  298. } else {
  299. $data = $one;
  300. }
  301. } else {
  302. $data = array($one => $two);
  303. }
  304. if ($data == null) {
  305. return false;
  306. }
  307. $this->__jsVars = array_merge($this->__jsVars, $data);
  308. }
  309. /**
  310. * Uses the selected JS engine to create a submit input
  311. * element that is enhanced with Javascript. Options can include
  312. * both those for FormHelper::submit() and JsBaseEngine::request(), JsBaseEngine::event();
  313. *
  314. * Forms submitting with this method, cannot send files. Files do not transfer over XmlHttpRequest
  315. * and require an iframe.
  316. *
  317. * @param string $title The display text of the submit button.
  318. * @param array $options Array of options to use.
  319. * @return string Completed submit button.
  320. */
  321. public function submit($caption = null, $options = array()) {
  322. if (!isset($options['id'])) {
  323. $options['id'] = 'submit-' . intval(mt_rand());
  324. }
  325. $formOptions = array('div');
  326. $htmlOptions = $this->_getHtmlOptions($options, $formOptions);
  327. $out = $this->Form->submit($caption, $htmlOptions);
  328. $this->get('#' . $htmlOptions['id']);
  329. $options['data'] = $this->serializeForm(array('isForm' => false, 'inline' => true));
  330. $requestString = $url = '';
  331. if (isset($options['confirm'])) {
  332. $requestString = $this->confirmReturn($options['confirm']);
  333. unset($options['confirm']);
  334. }
  335. if (isset($options['url'])) {
  336. $url = $options['url'];
  337. unset($options['url']);
  338. }
  339. if (!isset($options['method'])) {
  340. $options['method'] = 'post';
  341. }
  342. $options['dataExpression'] = true;
  343. $requestString .= $this->request($url, $options);
  344. if (!empty($requestString)) {
  345. $event = $this->event('click', $requestString, $options);
  346. }
  347. if (isset($options['buffer']) && $options['buffer'] == false) {
  348. $out .= $this->Html->scriptBlock($event, $options);
  349. }
  350. return $out;
  351. }
  352. /**
  353. * Parse a set of Options and extract the Html options.
  354. * Extracted Html Options are removed from the $options param.
  355. *
  356. * @param array $options Options to filter.
  357. * @param array $additional Array of additional keys to extract and include in the return options array.
  358. * @return array Array of options for non-js.
  359. */
  360. public function _getHtmlOptions(&$options, $additional = array()) {
  361. $htmlKeys = array_merge(array('class', 'id', 'escape', 'onblur', 'onfocus', 'rel', 'title'), $additional);
  362. $htmlOptions = array();
  363. foreach ($htmlKeys as $key) {
  364. if (isset($options[$key])) {
  365. $htmlOptions[$key] = $options[$key];
  366. }
  367. unset($options[$key]);
  368. }
  369. if (isset($options['htmlAttributes'])) {
  370. $htmlOptions = array_merge($htmlOptions, $options['htmlAttributes']);
  371. unset($options['htmlAttributes']);
  372. }
  373. return $htmlOptions;
  374. }
  375. }
  376. /**
  377. * JsEngineBaseClass
  378. *
  379. * Abstract Base Class for All JsEngines to extend. Provides generic methods.
  380. *
  381. * @package cake.view.helpers
  382. */
  383. class JsBaseEngineHelper extends AppHelper {
  384. /**
  385. * Determines whether native JSON extension is used for encoding. Set by object constructor.
  386. *
  387. * @var boolean
  388. * @access public
  389. */
  390. var $useNative = false;
  391. /**
  392. * The js snippet for the current selection.
  393. *
  394. * @var string
  395. * @access public
  396. */
  397. public $selection;
  398. /**
  399. * Collection of option maps. Option maps allow other helpers to use generic names for engine
  400. * callbacks and options. Allowing uniform code access for all engine types. Their use is optional
  401. * for end user use though.
  402. *
  403. * @var array
  404. */
  405. protected $_optionMap = array();
  406. /**
  407. * An array of lowercase method names in the Engine that are buffered unless otherwise disabled.
  408. * This allows specific 'end point' methods to be automatically buffered by the JsHelper.
  409. *
  410. * @var array
  411. */
  412. public $bufferedMethods = array('event', 'sortable', 'drag', 'drop', 'slider');
  413. /**
  414. * Contains a list of callback names -> default arguments.
  415. *
  416. * @var array
  417. */
  418. public $_callbackArguments = array();
  419. /**
  420. * Constructor.
  421. *
  422. * @return void
  423. */
  424. public function __construct() {
  425. $this->useNative = function_exists('json_encode');
  426. }
  427. /**
  428. * Create an alert message in Javascript
  429. *
  430. * @param string $message Message you want to alter.
  431. * @access public
  432. * @return string completed alert()
  433. */
  434. public function alert($message) {
  435. return 'alert("' . $this->escape($message) . '");';
  436. }
  437. /**
  438. * Redirects to a URL
  439. *
  440. * @param mixed $url
  441. * @param array $options
  442. * @return string completed redirect in javascript
  443. */
  444. public function redirect($url = null) {
  445. return 'window.location = "' . Router::url($url) . '";';
  446. }
  447. /**
  448. * Create a confirm() message
  449. *
  450. * @param string $message Message you want confirmed.
  451. * @access public
  452. * @return string completed confirm()
  453. */
  454. public function confirm($message) {
  455. return 'confirm("' . $this->escape($message) . '");';
  456. }
  457. /**
  458. * Generate a confirm snippet that returns false from the current
  459. * function scope.
  460. *
  461. * @param string $message Message to use in the confirm dialog.
  462. * @access public
  463. * @return string
  464. */
  465. public function confirmReturn($message) {
  466. $out = 'var _confirm = ' . $this->confirm($message);
  467. $out .= "if (!_confirm) {\n\treturn false;\n}";
  468. return $out;
  469. }
  470. /**
  471. * Create a prompt() Javascript function
  472. *
  473. * @param string $message Message you want to prompt.
  474. * @param string $default Default message
  475. * @access public
  476. * @return string completed prompt()
  477. */
  478. function prompt($message, $default = '') {
  479. return 'prompt("' . $this->escape($message) . '", "' . $this->escape($default) . '");';
  480. }
  481. /**
  482. * Generates a JavaScript object in JavaScript Object Notation (JSON)
  483. * from an array. Will use native JSON encode method if available, and $useNative == true
  484. *
  485. * Options:
  486. *
  487. * - `prefix` - String prepended to the returned data.
  488. * - `postfix` - String appended to the returned data.
  489. *
  490. * @param array $data Data to be converted.
  491. * @param array $options Set of options, see above.
  492. * @return string A JSON code block
  493. * @access public
  494. */
  495. public function object($data = array(), $options = array()) {
  496. $defaultOptions = array(
  497. 'prefix' => '', 'postfix' => '',
  498. );
  499. $options = array_merge($defaultOptions, $options);
  500. if (is_object($data)) {
  501. $data = get_object_vars($data);
  502. }
  503. $out = $keys = array();
  504. $numeric = true;
  505. if ($this->useNative && function_exists('json_encode')) {
  506. $rt = json_encode($data);
  507. } else {
  508. if (is_null($data)) {
  509. return 'null';
  510. }
  511. if (is_bool($data)) {
  512. return $data ? 'true' : 'false';
  513. }
  514. if (is_array($data)) {
  515. $keys = array_keys($data);
  516. }
  517. if (!empty($keys)) {
  518. $numeric = (array_values($keys) === array_keys(array_values($keys)));
  519. }
  520. foreach ($data as $key => $val) {
  521. if (is_array($val) || is_object($val)) {
  522. $val = $this->object($val, $options);
  523. } else {
  524. $val = $this->value($val);
  525. }
  526. if (!$numeric) {
  527. $val = '"' . $this->value($key, false) . '":' . $val;
  528. }
  529. $out[] = $val;
  530. }
  531. if (!$numeric) {
  532. $rt = '{' . join(',', $out) . '}';
  533. } else {
  534. $rt = '[' . join(',', $out) . ']';
  535. }
  536. }
  537. $rt = $options['prefix'] . $rt . $options['postfix'];
  538. return $rt;
  539. }
  540. /**
  541. * Converts a PHP-native variable of any type to a JSON-equivalent representation
  542. *
  543. * @param mixed $val A PHP variable to be converted to JSON
  544. * @param boolean $quoteStrings If false, leaves string values unquoted
  545. * @return string a JavaScript-safe/JSON representation of $val
  546. * @access public
  547. */
  548. public function value($val, $quoteString = true) {
  549. switch (true) {
  550. case (is_array($val) || is_object($val)):
  551. $val = $this->object($val);
  552. break;
  553. case ($val === null):
  554. $val = 'null';
  555. break;
  556. case (is_bool($val)):
  557. $val = ($val === true) ? 'true' : 'false';
  558. break;
  559. case (is_int($val)):
  560. $val = $val;
  561. break;
  562. case (is_float($val)):
  563. $val = sprintf("%.11f", $val);
  564. break;
  565. default:
  566. $val = $this->escape($val);
  567. if ($quoteString) {
  568. $val = '"' . $val . '"';
  569. }
  570. break;
  571. }
  572. return $val;
  573. }
  574. /**
  575. * Escape a string to be JSON friendly.
  576. *
  577. * List of escaped elements:
  578. *
  579. * + "\r" => '\n'
  580. * + "\n" => '\n'
  581. * + '"' => '\"'
  582. *
  583. * @param string $script String that needs to get escaped.
  584. * @return string Escaped string.
  585. * @access public
  586. */
  587. public function escape($string) {
  588. App::import('Core', 'Multibyte');
  589. return $this->_utf8ToHex($string);
  590. }
  591. /**
  592. * Encode a string into JSON. Converts and escapes necessary characters.
  593. *
  594. * @return void
  595. */
  596. protected function _utf8ToHex($string) {
  597. $length = strlen($string);
  598. $return = '';
  599. for ($i = 0; $i < $length; ++$i) {
  600. $ord = ord($string{$i});
  601. switch (true) {
  602. case $ord == 0x08:
  603. $return .= '\b';
  604. break;
  605. case $ord == 0x09:
  606. $return .= '\t';
  607. break;
  608. case $ord == 0x0A:
  609. $return .= '\n';
  610. break;
  611. case $ord == 0x0C:
  612. $return .= '\f';
  613. break;
  614. case $ord == 0x0D:
  615. $return .= '\r';
  616. break;
  617. case $ord == 0x22:
  618. case $ord == 0x2F:
  619. case $ord == 0x5C:
  620. $return .= '\\' . $string{$i};
  621. break;
  622. case (($ord >= 0x20) && ($ord <= 0x7F)):
  623. $return .= $string{$i};
  624. break;
  625. case (($ord & 0xE0) == 0xC0):
  626. if ($i + 1 >= $length) {
  627. $i += 1;
  628. $return .= '?';
  629. break;
  630. }
  631. $charbits = $string{$i} . $string{$i + 1};
  632. $char = Multibyte::utf8($charbits);
  633. $return .= sprintf('\u%04s', dechex($char[0]));
  634. $i += 1;
  635. break;
  636. case (($ord & 0xF0) == 0xE0):
  637. if ($i + 2 >= $length) {
  638. $i += 2;
  639. $return .= '?';
  640. break;
  641. }
  642. $charbits = $string{$i} . $string{$i + 1} . $string{$i + 2};
  643. $char = Multibyte::utf8($charbits);
  644. $return .= sprintf('\u%04s', dechex($char[0]));
  645. $i += 2;
  646. break;
  647. case (($ord & 0xF8) == 0xF0):
  648. if ($i + 3 >= $length) {
  649. $i += 3;
  650. $return .= '?';
  651. break;
  652. }
  653. $charbits = $string{$i} . $string{$i + 1} . $string{$i + 2} . $string{$i + 3};
  654. $char = Multibyte::utf8($charbits);
  655. $return .= sprintf('\u%04s', dechex($char[0]));
  656. $i += 3;
  657. break;
  658. case (($ord & 0xFC) == 0xF8):
  659. if ($i + 4 >= $length) {
  660. $i += 4;
  661. $return .= '?';
  662. break;
  663. }
  664. $charbits = $string{$i} . $string{$i + 1} . $string{$i + 2} . $string{$i + 3} . $string{$i + 4};
  665. $char = Multibyte::utf8($charbits);
  666. $return .= sprintf('\u%04s', dechex($char[0]));
  667. $i += 4;
  668. break;
  669. case (($ord & 0xFE) == 0xFC):
  670. if ($i + 5 >= $length) {
  671. $i += 5;
  672. $return .= '?';
  673. break;
  674. }
  675. $charbits = $string{$i} . $string{$i + 1} . $string{$i + 2} . $string{$i + 3} . $string{$i + 4} . $string{$i + 5};
  676. $char = Multibyte::utf8($charbits);
  677. $return .= sprintf('\u%04s', dechex($char[0]));
  678. $i += 5;
  679. break;
  680. }
  681. }
  682. return $return;
  683. }
  684. /**
  685. * Create javascript selector for a CSS rule
  686. *
  687. * @param string $selector The selector that is targeted
  688. * @return object instance of $this. Allows chained methods.
  689. */
  690. public function get($selector) {
  691. trigger_error(sprintf(__('%s does not have get() implemented', true), get_class($this)), E_USER_WARNING);
  692. return $this;
  693. }
  694. /**
  695. * Add an event to the script cache. Operates on the currently selected elements.
  696. *
  697. * ### Options
  698. *
  699. * - `wrap` - Whether you want the callback wrapped in an anonymous function. (defaults to true)
  700. * - `stop` - Whether you want the event to stopped. (defaults to true)
  701. *
  702. * @param string $type Type of event to bind to the current dom id
  703. * @param string $callback The Javascript function you wish to trigger or the function literal
  704. * @param array $options Options for the event.
  705. * @return string completed event handler
  706. */
  707. public function event($type, $callback, $options = array()) {
  708. trigger_error(sprintf(__('%s does not have event() implemented', true), get_class($this)), E_USER_WARNING);
  709. }
  710. /**
  711. * Create a domReady event. This is a special event in many libraries
  712. *
  713. * @param string $functionBody The code to run on domReady
  714. * @return string completed domReady method
  715. */
  716. public function domReady($functionBody) {
  717. trigger_error(sprintf(__('%s does not have domReady() implemented', true), get_class($this)), E_USER_WARNING);
  718. }
  719. /**
  720. * Create an iteration over the current selection result.
  721. *
  722. * @param string $callback The function body you wish to apply during the iteration.
  723. * @return string completed iteration
  724. */
  725. public function each($callback) {
  726. trigger_error(sprintf(__('%s does not have each() implemented', true), get_class($this)), E_USER_WARNING);
  727. }
  728. /**
  729. * Trigger an Effect.
  730. *
  731. * ### Supported Effects
  732. *
  733. * The following effects are supported by all JsEngines
  734. *
  735. * - `show` - reveal an element.
  736. * - `hide` - hide an element.
  737. * - `fadeIn` - Fade in an element.
  738. * - `fadeOut` - Fade out an element.
  739. * - `slideIn` - Slide an element in.
  740. * - `slideOut` - Slide an element out.
  741. *
  742. * ### Options
  743. *
  744. * - `speed` - Speed at which the animation should occur. Accepted values are 'slow', 'fast'. Not all effects use
  745. * the speed option.
  746. *
  747. * @param string $name The name of the effect to trigger.
  748. * @param array $options Array of options for the effect.
  749. * @return string completed string with effect.
  750. */
  751. public function effect($name, $options) {
  752. trigger_error(sprintf(__('%s does not have effect() implemented', true), get_class($this)), E_USER_WARNING);
  753. }
  754. /**
  755. * Make an XHR request
  756. *
  757. * ### Event Options
  758. *
  759. * - `complete` - Callback to fire on complete.
  760. * - `success` - Callback to fire on success.
  761. * - `before` - Callback to fire on request initialization.
  762. * - `error` - Callback to fire on request failure.
  763. *
  764. * ### Options
  765. *
  766. * - `method` - The method to make the request with defaults to GET in more libraries
  767. * - `async` - Whether or not you want an asynchronous request.
  768. * - `data` - Additional data to send.
  769. * - `update` - Dom id to update with the content of the request.
  770. * - `type` - Data type for response. 'json' and 'html' are supported. Default is html for most libraries.
  771. * - `evalScripts` - Whether or not <script> tags should be eval'ed.
  772. * - `dataExpression` - Should the `data` key be treated as a callback. Useful for supplying `$options['data']` as
  773. * another Javascript expression.
  774. *
  775. * @param mixed $url Array or String URL to target with the request.
  776. * @param array $options Array of options. See above for cross library supported options
  777. * @return string XHR request.
  778. */
  779. public function request($url, $options = array()) {
  780. trigger_error(sprintf(__('%s does not have request() implemented', true), get_class($this)), E_USER_WARNING);
  781. }
  782. /**
  783. * Create a draggable element. Works on the currently selected element.
  784. * Additional options may be supported by your library.
  785. *
  786. * ### Options
  787. *
  788. * - `handle` - selector to the handle element.
  789. * - `snapGrid` - The pixel grid that movement snaps to, an array(x, y)
  790. * - `container` - The element that acts as a bounding box for the draggable element.
  791. *
  792. * ### Event Options
  793. *
  794. * - `start` - Event fired when the drag starts
  795. * - `drag` - Event fired on every step of the drag
  796. * - `stop` - Event fired when dragging stops (mouse release)
  797. *
  798. * @param array $options Options array see above.
  799. * @return string Completed drag script
  800. */
  801. public function drag($options = array()) {
  802. trigger_error(sprintf(__('%s does not have drag() implemented', true), get_class($this)), E_USER_WARNING);
  803. }
  804. /**
  805. * Create a droppable element. Allows for draggable elements to be dropped on it.
  806. * Additional options may be supported by your library.
  807. *
  808. * ### Options
  809. *
  810. * - `accept` - Selector for elements this droppable will accept.
  811. * - `hoverclass` - Class to add to droppable when a draggable is over.
  812. *
  813. * ### Event Options
  814. *
  815. * - `drop` - Event fired when an element is dropped into the drop zone.
  816. * - `hover` - Event fired when a drag enters a drop zone.
  817. * - `leave` - Event fired when a drag is removed from a drop zone without being dropped.
  818. *
  819. * @return string Completed drop script
  820. */
  821. public function drop($options = array()) {
  822. trigger_error(sprintf(__('%s does not have drop() implemented', true), get_class($this)), E_USER_WARNING);
  823. }
  824. /**
  825. * Create a sortable element.
  826. *
  827. * ### Options
  828. *
  829. * - `containment` - Container for move action
  830. * - `handle` - Selector to handle element. Only this element will start sort action.
  831. * - `revert` - Whether or not to use an effect to move sortable into final position.
  832. * - `opacity` - Opacity of the placeholder
  833. * - `distance` - Distance a sortable must be dragged before sorting starts.
  834. *
  835. * ### Event Options
  836. *
  837. * - `start` - Event fired when sorting starts
  838. * - `sort` - Event fired during sorting
  839. * - `complete` - Event fired when sorting completes.
  840. *
  841. * @param array $options Array of options for the sortable. See above.
  842. * @return string Completed sortable script.
  843. */
  844. public function sortable() {
  845. trigger_error(sprintf(__('%s does not have sortable() implemented', true), get_class($this)), E_USER_WARNING);
  846. }
  847. /**
  848. * Create a slider UI widget. Comprised of a track and knob
  849. *
  850. * ### Options
  851. *
  852. * - `handle` - The id of the element used in sliding.
  853. * - `direction` - The direction of the slider either 'vertical' or 'horizontal'
  854. * - `min` - The min value for the slider.
  855. * - `max` - The max value for the slider.
  856. * - `step` - The number of steps or ticks the slider will have.
  857. * - `value` - The initial offset of the slider.
  858. *
  859. * ### Events
  860. *
  861. * - `change` - Fired when the slider's value is updated
  862. * - `complete` - Fired when the user stops sliding the handle
  863. *
  864. * @return string Completed slider script
  865. */
  866. public function slider() {
  867. trigger_error(sprintf(__('%s does not have slider() implemented', true), get_class($this)), E_USER_WARNING);
  868. }
  869. /**
  870. * Serialize the form attached to $selector.
  871. * Pass `true` for $isForm if the current selection is a form element.
  872. * Converts the form or the form element attached to the current selection into a string/json object
  873. * (depending on the library implementation) for use with XHR operations.
  874. *
  875. * ### Options
  876. *
  877. * - `isForm` - is the current selection a form, or an input? (defaults to false)
  878. * - `inline` - is the rendered statement going to be used inside another JS statement? (defaults to false)
  879. *
  880. * @param array $options options for serialization generation.
  881. * @return string completed form serialization script
  882. */
  883. public function serializeForm() {
  884. trigger_error(
  885. sprintf(__('%s does not have serializeForm() implemented', true), get_class($this)), E_USER_WARNING
  886. );
  887. }
  888. /**
  889. * Parse an options assoc array into an Javascript object literal.
  890. * Similar to object() but treats any non-integer value as a string,
  891. * does not include { }
  892. *
  893. * @param array $options Options to be converted
  894. * @param array $safeKeys Keys that should not be escaped.
  895. * @return string
  896. * @access protected
  897. */
  898. protected function _parseOptions($options, $safeKeys = array()) {
  899. $out = array();
  900. $safeKeys = array_flip($safeKeys);
  901. foreach ($options as $key => $value) {
  902. if (!is_int($value) && !isset($safeKeys[$key])) {
  903. $value = $this->value($value);
  904. }
  905. $out[] = $key . ':' . $value;
  906. }
  907. sort($out);
  908. return join(', ', $out);
  909. }
  910. /**
  911. * Maps Abstract options to engine specific option names.
  912. * If attributes are missing from the map, they are not changed.
  913. *
  914. * @param string $method Name of method whose options are being worked with.
  915. * @param array $options Array of options to map.
  916. * @return array Array of mapped options.
  917. * @access protected
  918. */
  919. protected function _mapOptions($method, $options) {
  920. if (!isset($this->_optionMap[$method])) {
  921. return $options;
  922. }
  923. foreach ($this->_optionMap[$method] as $abstract => $concrete) {
  924. if (isset($options[$abstract])) {
  925. $options[$concrete] = $options[$abstract];
  926. unset($options[$abstract]);
  927. }
  928. }
  929. return $options;
  930. }
  931. /**
  932. * Prepare callbacks and wrap them with function ([args]) { } as defined in
  933. * _callbackArgs array.
  934. *
  935. * @param string $method Name of the method you are preparing callbacks for.
  936. * @param array $options Array of options being parsed
  937. * @param string $callbacks Additional Keys that contain callbacks
  938. * @access protected
  939. * @return array Array of options with callbacks added.
  940. */
  941. protected function _prepareCallbacks($method, $options, $callbacks = array()) {
  942. $wrapCallbacks = true;
  943. if (isset($options['wrapCallbacks'])) {
  944. $wrapCallbacks = $options['wrapCallbacks'];
  945. }
  946. unset($options['wrapCallbacks']);
  947. if (!$wrapCallbacks) {
  948. return $options;
  949. }
  950. $callbackOptions = array();
  951. if (isset($this->_callbackArguments[$method])) {
  952. $callbackOptions = $this->_callbackArguments[$method];
  953. }
  954. $callbacks = array_unique(array_merge(array_keys($callbackOptions), (array)$callbacks));
  955. foreach ($callbacks as $callback) {
  956. if (empty($options[$callback])) {
  957. continue;
  958. }
  959. $args = null;
  960. if (!empty($callbackOptions[$callback])) {
  961. $args = $callbackOptions[$callback];
  962. }
  963. $options[$callback] = 'function (' . $args . ') {' . $options[$callback] . '}';
  964. }
  965. return $options;
  966. }
  967. /**
  968. * Conveinence wrapper method for all common option processing steps.
  969. * Runs _mapOptions, _prepareCallbacks, and _parseOptions in order.
  970. *
  971. * @param string $method Name of method processing options for.
  972. * @param array $options Array of options to process.
  973. * @return string Parsed options string.
  974. */
  975. protected function _processOptions($method, $options) {
  976. $options = $this->_mapOptions($method, $options);
  977. $options = $this->_prepareCallbacks($method, $options);
  978. $options = $this->_parseOptions($options, array_keys($this->_callbackArguments[$method]));
  979. return $options;
  980. }
  981. /**
  982. * Convert an array of data into a query string
  983. *
  984. * @param array $parameters Array of parameters to convert to a query string
  985. * @return string Querystring fragment
  986. * @access protected
  987. */
  988. protected function _toQuerystring($parameters) {
  989. $out = '';
  990. $keys = array_keys($parameters);
  991. $count = count($parameters);
  992. for ($i = 0; $i < $count; $i++) {
  993. $out .= $keys[$i] . '=' . $parameters[$keys[$i]];
  994. if ($i < $count - 1) {
  995. $out .= '&';
  996. }
  997. }
  998. return $out;
  999. }
  1000. }
  1001. ?>