PageRenderTime 52ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/branches/jsrewrite/jfx-private/classes/PHPQuery/phpQueryEvents.php

http://jfxcms.googlecode.com/
PHP | 151 lines | 103 code | 0 blank | 48 comment | 26 complexity | f888400a0edd12925b93416dfff3f3f3 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1
  1. <?php
  2. /**
  3. * Event handling class.
  4. *
  5. * @author Tobiasz Cudnik
  6. * @package phpQuery
  7. * @static
  8. */
  9. class phpQueryEvents {
  10. /**
  11. * Trigger a type of event on every matched element.
  12. *
  13. * @param DOMNode|phpQueryObject|string $document
  14. * @param unknown_type $type
  15. * @param unknown_type $data
  16. *
  17. * @TODO exclusive events (with !)
  18. * @TODO global events
  19. * @TODO support more than event in $type (space-separated)
  20. */
  21. public static function trigger($document, $type, $data = array(), $node = null) {
  22. // trigger: function(type, data, elem, donative, extra) {
  23. $documentID = phpQuery::getDocumentID($document);
  24. $namespace = null;
  25. if (strpos($type, '.') !== false)
  26. list($name, $namespace) = explode('.', $type);
  27. else
  28. $name = $type;
  29. if (! $node) {
  30. if (self::issetGlobal($documentID, $type)) {
  31. $pq = phpQuery::getDocument($documentID);
  32. // TODO check add($pq->document)
  33. $pq->find('*')->add($pq->document)
  34. ->trigger($type, $data);
  35. }
  36. } else {
  37. if (isset($data[0]) && $data[0] instanceof DOMEvent) {
  38. $event = $data[0];
  39. $event->relatedTarget = $event->target;
  40. $event->target = $node;
  41. $data = array_slice($data, 1);
  42. } else {
  43. $event = new DOMEvent(array(
  44. 'type' => $type,
  45. 'target' => $node,
  46. 'timeStamp' => time(),
  47. ));
  48. }
  49. while($node) {
  50. phpQuery::debug("Triggering event '{$type}' on node ".phpQueryObject::whois($node)."\n");
  51. $event->currentTarget = $node;
  52. $eventNode = self::getNode($documentID, $node);
  53. if (isset($eventNode->eventHandlers)) {
  54. foreach($eventNode->eventHandlers as $eventType => $handlers) {
  55. $eventNamespace = null;
  56. if (strpos($type, '.') !== false)
  57. list($eventName, $eventNamespace) = explode('.', $eventType);
  58. else
  59. $eventName = $eventType;
  60. if ($name != $eventName)
  61. continue;
  62. if ($namespace && $eventNamespace && $namespace != $eventNamespace)
  63. continue;
  64. foreach($handlers as $handler) {
  65. $event->data = $handler['data']
  66. ? $handler['data']
  67. : null;
  68. $return = phpQuery::callbackRun($handler['callback'], array_merge(array($event), $data));
  69. }
  70. if ($return === false) {
  71. $event->bubbles = false;
  72. }
  73. }
  74. }
  75. // to bubble or not to bubble...
  76. if (! $event->bubbles)
  77. break;
  78. $node = $node->parentNode;
  79. }
  80. }
  81. }
  82. /**
  83. * Binds a handler to one or more events (like click) for each matched element.
  84. * Can also bind custom events.
  85. *
  86. * @param DOMNode|phpQueryObject|string $document
  87. * @param unknown_type $type
  88. * @param unknown_type $data Optional
  89. * @param unknown_type $callback
  90. *
  91. * @TODO support '!' (exclusive) events
  92. * @TODO support more than event in $type (space-separated)
  93. * @TODO support binding to global events
  94. */
  95. public static function add($document, $node, $type, $data, $callback = null) {
  96. $documentID = phpQuery::getDocumentID($document);
  97. // if (is_null($callback) && is_callable($data)) {
  98. // $callback = $data;
  99. // $data = null;
  100. // }
  101. $eventNode = self::getNode($documentID, $node);
  102. if (! $eventNode)
  103. $eventNode = self::setNode($documentID, $node);
  104. if (!isset($eventNode->eventHandlers[$type]))
  105. $eventNode->eventHandlers[$type] = array();
  106. $eventNode->eventHandlers[$type][] = array(
  107. 'callback' => $callback,
  108. 'data' => $data,
  109. );
  110. }
  111. /**
  112. * Enter description here...
  113. *
  114. * @param DOMNode|phpQueryObject|string $document
  115. * @param unknown_type $type
  116. * @param unknown_type $callback
  117. *
  118. * @TODO namespace events
  119. * @TODO support more than event in $type (space-separated)
  120. */
  121. public static function remove($document, $node, $type = null, $callback = null) {
  122. $documentID = phpQuery::getDocumentID($document);
  123. $eventNode = self::getNode($documentID, $node);
  124. if (is_object($eventNode) && isset($eventNode->eventHandlers[$type])) {
  125. if ($callback) {
  126. foreach($eventNode->eventHandlers[$type] as $k => $handler)
  127. if ($handler['callback'] == $callback)
  128. unset($eventNode->eventHandlers[$type][$k]);
  129. } else {
  130. unset($eventNode->eventHandlers[$type]);
  131. }
  132. }
  133. }
  134. protected static function getNode($documentID, $node) {
  135. foreach(phpQuery::$documents[$documentID]['eventNodes'] as $eventNode) {
  136. if ($node->isSameNode($eventNode))
  137. return $eventNode;
  138. }
  139. }
  140. protected static function setNode($documentID, $node) {
  141. phpQuery::$documents[$documentID]['eventNodes'][] = $node;
  142. return phpQuery::$documents[$documentID]['eventNodes'][
  143. count(phpQuery::$documents[$documentID]['eventNodes'])-1
  144. ];
  145. }
  146. protected static function issetGlobal($documentID, $type) {
  147. return isset(phpQuery::$documents[$documentID])
  148. ? in_array($type, phpQuery::$documents[$documentID]['eventGlobals'])
  149. : false;
  150. }
  151. }