Skip to content

Commit e32cdd0

Browse files
committed
Merge pull request #331 from cakephp/ajax-panel
Implemented Ajax planel, closes #261
2 parents 377ee67 + 05dab3d commit e32cdd0

File tree

6 files changed

+123
-3
lines changed

6 files changed

+123
-3
lines changed

src/Panel/HistoryPanel.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,14 @@ public function data()
3737
'requests' => $recent->toArray(),
3838
];
3939
}
40+
41+
/**
42+
* Gets the initial text for the history summary
43+
*
44+
* @return string
45+
*/
46+
public function summary()
47+
{
48+
return '0 xhr';
49+
}
4050
}

src/Routing/Filter/DebugBarFilter.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ public function afterDispatch(Event $event)
209209
$row = $requests->save($row);
210210

211211
$this->_injectScripts($row->id, $response);
212+
$response->header(['X-DEBUGKIT-ID' => $row->id]);
212213
}
213214

214215
/**

src/Template/Element/history_panel.ctp

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
*/
1414
use Cake\Routing\Router;
1515
?>
16+
<div id="request-history">
1617
<?php if (empty($requests)): ?>
1718
<p class="warning"><?= __d('debug_kit', 'No previous requests logged.') ?></p>
1819
<?php else: ?>
@@ -39,12 +40,62 @@ use Cake\Routing\Router;
3940
<?php endforeach; ?>
4041
</ul>
4142
<?php endif; ?>
43+
</div>
44+
<script type="text/html" id="list-template">
45+
<ul class="history-list">
46+
<li>
47+
<?= $this->Html->link(
48+
__d('debug_kit', 'Back to current request'),
49+
['plugin' => 'DebugKit', 'controller' => 'Panels', 'action' => 'index', $panel->request_id],
50+
['class' => 'history-link', 'data-request' => $panel->request_id]
51+
) ?>
52+
</li>
53+
</ul>
54+
</script>
55+
56+
<script type="text/html" id="list-item-template">
57+
<li>
58+
<?php $url = ['plugin' => 'DebugKit', 'controller' => 'Panels', 'action' => 'index'] ?>
59+
<a class="history-link" data-request="{id}" href="<?= $this->Url->build($url) ?>/{id}">
60+
<span class="history-time">{time}</span>
61+
<span class="history-bubble xhr">XHR</span>
62+
<span class="history-bubble">{method}</span>
63+
<span class="history-bubble">{status}</span>
64+
<span class="history-bubble">{type}</span>
65+
<span class="history-url">{url}</span>
66+
</a>
67+
</li>
68+
</script>
69+
4270
<script>
4371
$(document).ready(function() {
4472
var panelButtons = $('.panel');
4573
var thisPanel = '<?= h($panel->id) ?>';
46-
var buttons = $('.history-link');
74+
var toolbar = window.toolbar;
75+
76+
if (!$('#request-history > ul').length) {
77+
$('#request-history').html($('#list-template').html());
78+
}
4779

80+
var listItem = $('#list-item-template').html();
81+
82+
for (var i = 0; i < toolbar.ajaxRequests.length; i++) {
83+
var params = {
84+
id: toolbar.ajaxRequests[i].requestId,
85+
time: (new Date(toolbar.ajaxRequests[i].date)).toLocaleString(),
86+
method: toolbar.ajaxRequests[i].method,
87+
status: toolbar.ajaxRequests[i].status,
88+
url: toolbar.ajaxRequests[i].url,
89+
type: toolbar.ajaxRequests[i].type
90+
};
91+
var content = listItem.replace(/{([^{}]*)}/g, function(a, b) {
92+
var r = params[b];
93+
return typeof r === 'string' || typeof r === 'number' ? r : a;
94+
});
95+
$('ul.history-list li:first').after(content);
96+
}
97+
98+
var buttons = $('.history-link');
4899
// Highlight the active request.
49100
buttons.filter('[data-request=' + window.toolbar.currentRequest + ']').addClass('active');
50101

webroot/css/toolbar.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,10 @@ table tbody tr:nth-child(odd) {
352352
padding: 2px;
353353
border-radius: 4px;
354354
}
355+
356+
.xhr {
357+
background:#7CFF46
358+
}
355359
.history-time {
356360
font-size: 12px;
357361
display: block;

webroot/js/toolbar-app.js

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ Toolbar.prototype = {
1414
_state: 0,
1515
currentRequest: null,
1616
originalRequest: null,
17+
ajaxRequests: [],
1718

1819
states: [
1920
'collapse',
@@ -158,7 +159,7 @@ Toolbar.prototype = {
158159
// Close active panel
159160
if (_this.isExpanded()) {
160161
return _this.hideContent();
161-
}
162+
}
162163
// Collapse the toolbar
163164
if (_this.state() === "toolbar") {
164165
return _this.toggle();
@@ -180,7 +181,7 @@ Toolbar.prototype = {
180181
if (nextPanel.hasClass('panel')) {
181182
nextPanel.addClass('panel-active');
182183
return _this.loadPanel(nextPanel.data('id'));
183-
}
184+
}
184185
}
185186
});
186187
},
@@ -221,10 +222,26 @@ Toolbar.prototype = {
221222
}
222223
},
223224

225+
onMessage: function(event) {
226+
if (event.data.indexOf('ajax-completed$$') === 0) {
227+
this.onRequest(JSON.parse(event.data.split('$$')[1]))
228+
}
229+
},
230+
231+
onRequest: function(request) {
232+
this.ajaxRequests.push(request);
233+
$(".panel-summary:contains(xhr)").text("" + this.ajaxRequests.length + ' xhr');
234+
},
235+
224236
initialize: function() {
225237
this.windowOrigin();
226238
this.mouseListener();
227239
this.keyboardListener();
228240
this.loadState();
241+
242+
var self = this;
243+
window.addEventListener('message', function (event) {
244+
self.onMessage(event);
245+
}, false);
229246
}
230247
};

webroot/js/toolbar.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,46 @@
4141
window.addEventListener('message', onMessage, false);
4242
};
4343

44+
var logAjaxRequest = function(original) {
45+
return function() {
46+
if (this.readyState === 4 && this.getResponseHeader('X-DEBUGKIT-ID')) {
47+
var params = {
48+
requestId: this.getResponseHeader('X-DEBUGKIT-ID'),
49+
status: this.status,
50+
date: new Date,
51+
method: this._arguments[0],
52+
url: this._arguments[1],
53+
type: this.getResponseHeader('Content-Type')
54+
}
55+
iframe.contentWindow.postMessage('ajax-completed$$' + JSON.stringify(params), window.location.origin);
56+
}
57+
if (original) {
58+
return original.apply(this, [].slice.call(arguments));
59+
}
60+
};
61+
};
62+
63+
var proxyAjaxOpen = function() {
64+
var proxied = window.XMLHttpRequest.prototype.open;
65+
window.XMLHttpRequest.prototype.open = function() {
66+
this._arguments = arguments;
67+
return proxied.apply(this, [].slice.call(arguments));
68+
};
69+
};
70+
71+
var proxyAjaxSend = function() {
72+
var proxied = window.XMLHttpRequest.prototype.send;
73+
window.XMLHttpRequest.prototype.send = function() {
74+
this.onreadystatechange = logAjaxRequest(this.onreadystatechange);
75+
return proxied.apply(this, [].slice.call(arguments));
76+
};
77+
};
78+
4479
// Bind on ready callback.
4580
if (doc.addEventListener) {
4681
doc.addEventListener('DOMContentLoaded', onReady, false);
82+
doc.addEventListener('DOMContentLoaded', proxyAjaxOpen, false);
83+
doc.addEventListener('DOMContentLoaded', proxyAjaxSend, false);
4784
} else {
4885
throw new Error('Unable to add event listener for DebugKit. Please use a browser' +
4986
'that supports addEventListener().')

0 commit comments

Comments
 (0)