Skip to content

Commit d30121b

Browse files
authored
Fix #117: Show arguments table by click
1 parent 18d3707 commit d30121b

File tree

6 files changed

+207
-43
lines changed

6 files changed

+207
-43
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
## 3.2.2 under development
44

5+
- Enh #117: Show arguments table by click (@xepozz)
56
- Enh #116: Remove @anonymous postfix (@xepozz)
67
- Bug #114: Stop `click` event on text selection (@xepozz)
78
- Enh #114: Show full argument by click (@xepozz)

src/Renderer/HtmlRenderer.php

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,16 @@ public function renderPreviousExceptions(Throwable $t): string
245245
public function renderCallStack(Throwable $t, array $trace = []): string
246246
{
247247
$application = $vendor = [];
248-
$application[1] = $this->renderCallStackItem($t->getFile(), $t->getLine(), null, null, [], 1, false);
248+
$application[1] = $this->renderCallStackItem(
249+
$t->getFile(),
250+
$t->getLine(),
251+
null,
252+
null,
253+
[],
254+
1,
255+
false,
256+
[],
257+
);
249258

250259
$length = count($trace);
251260
for ($i = 0; $i < $length; ++$i) {
@@ -254,18 +263,39 @@ public function renderCallStack(Throwable $t, array $trace = []): string
254263
$class = !empty($trace[$i]['class']) ? $trace[$i]['class'] : null;
255264
$args = !empty($trace[$i]['args']) ? $trace[$i]['args'] : [];
256265

266+
$parameters = [];
257267
$function = null;
258268
if (!empty($trace[$i]['function']) && $trace[$i]['function'] !== 'unknown') {
259269
$function = $trace[$i]['function'];
270+
if ($class !== null) {
271+
$parameters = (new \ReflectionMethod($class, $function))->getParameters();
272+
}
260273
}
261274
$index = $i + 2;
262275

263-
if ($isVendor = $this->isVendorFile($file)) {
264-
$vendor[$index] = $this->renderCallStackItem($file, $line, $class, $function, $args, $index, $isVendor);
265-
continue;
276+
if ($this->isVendorFile($file)) {
277+
$vendor[$index] = $this->renderCallStackItem(
278+
$file,
279+
$line,
280+
$class,
281+
$function,
282+
$args,
283+
$index,
284+
true,
285+
$parameters,
286+
);
287+
} else {
288+
$application[$index] = $this->renderCallStackItem(
289+
$file,
290+
$line,
291+
$class,
292+
$function,
293+
$args,
294+
$index,
295+
false,
296+
$parameters,
297+
);
266298
}
267-
268-
$application[$index] = $this->renderCallStackItem($file, $line, $class, $function, $args, $index, $isVendor);
269299
}
270300

271301
return $this->renderTemplate($this->defaultTemplatePath . '/_call-stack-items.php', [
@@ -302,7 +332,7 @@ public function argumentsToString(array $args, bool $truncate = true): string
302332
}
303333

304334
if (is_object($value)) {
305-
$args[$key] = '<span class="title">' . $this->htmlEncode($this->removeAnonymous($value::class)) . '</span>';
335+
$args[$key] = '<span class="title">' . $this->htmlEncode($this->removeAnonymous($value::class) . '#' . spl_object_id($value)) . '</span>';
306336
} elseif (is_bool($value)) {
307337
$args[$key] = '<span class="keyword">' . ($value ? 'true' : 'false') . '</span>';
308338
} elseif (is_string($value)) {
@@ -498,7 +528,8 @@ private function renderCallStackItem(
498528
?string $function,
499529
array $args,
500530
int $index,
501-
bool $isVendorFile
531+
bool $isVendorFile,
532+
array $reflectionParameters,
502533
): string {
503534
$lines = [];
504535
$begin = $end = 0;
@@ -525,6 +556,7 @@ private function renderCallStackItem(
525556
'end' => $end,
526557
'args' => $args,
527558
'isVendorFile' => $isVendorFile,
559+
'reflectionParameters' => $reflectionParameters,
528560
]);
529561
}
530562

templates/_call-stack-item.php

Lines changed: 50 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,23 @@
11
<?php
2-
/* @var $file string|null */
3-
/* @var $line int|null */
4-
/* @var $class string|null */
5-
/* @var $function string|null */
6-
/* @var $index int */
7-
/* @var $lines string[] */
8-
/* @var $begin int */
9-
/* @var $end int */
10-
/* @var $args array */
11-
/* @var $isVendorFile bool */
12-
/* @var $this \Yiisoft\ErrorHandler\Renderer\HtmlRenderer */
2+
3+
use Yiisoft\ErrorHandler\Renderer\HtmlRenderer;
4+
5+
/**
6+
* @var $file string|null
7+
* @var $line int|null
8+
* @var $class string|null
9+
* @var $function string|null
10+
* @var $index int
11+
* @var $lines string[]
12+
* @var $begin int
13+
* @var $end int
14+
* @var $args array
15+
* @var $isVendorFile bool
16+
* @var $reflectionParameters ReflectionMethod[]
17+
* @var $this HtmlRenderer
18+
*/
19+
20+
1321
$icon = <<<HTML
1422
<svg class="external-link" width="20" height="20" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
1523
<title>Open the target page</title>
@@ -32,7 +40,7 @@
3240
<?php endif ?>
3341

3442
<?php if ($function !== null): ?>
35-
<span class="function-info">
43+
<span class="function-info word-break">
3644
<?php
3745
echo $file === null ? "{$index}." : '&mdash;&nbsp;';
3846
$function = $class === null ? $function : "{$this->removeAnonymous($class)}::$function";
@@ -48,9 +56,38 @@
4856
</div>
4957

5058
<?php if ($line !== null): ?>
51-
<div><?= sprintf('at line %d', $line + 1) ?></div>
59+
<div class="flex flex-column">
60+
<?= sprintf('at line %d', $line + 1) ?>
61+
<?php if (!empty($args)): ?>
62+
<button class="show-arguments-toggle">arguments</button>
63+
<?php endif ?>
64+
</div>
5265
<?php endif ?>
5366
</div>
67+
<div class="function-arguments-wrap hidden">
68+
<?php
69+
if ($function !== null) {
70+
echo '<table class="table w-100">';
71+
foreach ($args as $key => $argument) {
72+
echo '<tr class="argument">';
73+
$key = is_int($key) && isset($reflectionParameters[$key]) ? $reflectionParameters[$key]->getName() : $key;
74+
echo '<td>';
75+
echo '<span class="argument-key bold">$' . $this->htmlEncode($key) . '</span>';
76+
echo '</td>';
77+
echo '<td>';
78+
echo '<span class="argument-value word-break">';
79+
echo $this->argumentsToString(is_array($argument) ? $argument : [$argument]);
80+
echo '</span>';
81+
echo '<span class="argument-type">';
82+
echo gettype($argument);
83+
echo '</span>';
84+
echo '</td>';
85+
echo '</tr>';
86+
}
87+
echo '</table>';
88+
}
89+
?>
90+
</div>
5491
<?php if (!empty($lines)): ?>
5592
<div class="element-code-wrap">
5693
<div class="code-wrap">

templates/development.css

Lines changed: 97 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,70 @@ ul {
4040
--page-text-color: #505050;
4141
--icon-color: #505050;
4242
--icon-hover-color: #000;
43+
--table-line-even-bg: #fff;
44+
--table-line-even-color: #141414;
45+
--table-line-odd-bg: #eee;
46+
--table-line-odd-color: #141414;
47+
--table-line-hover: #ccc;
48+
--button-bg: #eee;
49+
--button-color: #000;
50+
--button-bg-hover: #d4d4d4;
51+
--button-color-hover: #333;
52+
}
53+
54+
.table {
55+
border-collapse: collapse;
56+
width: 100%;
57+
}
58+
59+
.table td, .table th {
60+
border: 1px solid #ddd;
61+
padding: 8px;
62+
}
63+
64+
.table tr:nth-child(odd) {
65+
border-color: var(--table-line-odd-bg);
66+
background-color: var(--table-line-odd-bg);
67+
color: var(--table-line-odd-color);
68+
}
69+
70+
.table tr:nth-child(even) {
71+
border-color: var(--table-line-even-bg);
72+
background-color: var(--table-line-even-bg);
73+
color: var(--table-line-even-color);
74+
}
75+
76+
.table tr:hover {
77+
background-color: var(--table-line-hover);
78+
}
79+
80+
.argument-type {
81+
padding-left: 4px;
82+
opacity: 0.5;
83+
user-select: none;
84+
-webkit-user-select: none;
85+
-moz-user-select: none;
86+
-ms-user-select: none;
87+
display: none;
88+
}
89+
90+
.argument:hover .argument-type {
91+
display: inline;
92+
}
93+
94+
button.show-arguments-toggle {
95+
padding: 4px;
96+
font-size: 14px;
97+
box-sizing: border-box;
98+
border: 1px solid #ddd;
99+
background: var(--button-bg);
100+
color: var(--button-color)
101+
}
102+
103+
button.show-arguments-toggle:hover {
104+
border-color: var(--button-bg-hover);
105+
background: var(--button-bg-hover);
106+
color: var(--button-color-hover);
43107
}
44108

45109
header {
@@ -381,6 +445,14 @@ main {
381445
display: none;
382446
}
383447

448+
.flex {
449+
display: flex;
450+
}
451+
452+
.flex-column {
453+
flex-direction: column;
454+
}
455+
384456
.flex-1 {
385457
flex: 1;
386458
}
@@ -389,6 +461,19 @@ main {
389461
max-width: 100%;
390462
}
391463

464+
.w-100 {
465+
width: 100%;
466+
}
467+
468+
.bold {
469+
font-weight: bold;
470+
}
471+
472+
.word-break {
473+
overflow-wrap: break-word;
474+
word-break: break-word;
475+
}
476+
392477
/* call stack */
393478
.call-stack ul li,
394479
.request {
@@ -467,8 +552,6 @@ main {
467552
.call-stack ul li .element-wrap .function-info {
468553
display: inline-block;
469554
line-break: normal;
470-
overflow-wrap: break-word;
471-
word-break: break-word;
472555
}
473556

474557
.call-stack ul li.application .element-wrap {
@@ -681,10 +764,21 @@ main {
681764
/* start dark-theme */
682765

683766
.dark-theme {
684-
--page-bg-color: rgba(46,46,46, 0.9);
767+
--page-bg-color: rgba(46, 46, 46, 0.9);
685768
--page-text-color: #fff;
686769
--icon-color: #989898;
687770
--icon-hover-color: #fff;
771+
772+
--table-line-even-bg: #555;
773+
--table-line-even-color: #eee;
774+
--table-line-odd-bg: #999;
775+
--table-line-odd-color: #eee;
776+
--table-line-hover: #141414;
777+
778+
--button-bg: #666;
779+
--button-color: #fff;
780+
--button-bg-hover: #aaa;
781+
--button-color-hover: #333;
688782
}
689783

690784
.dark-theme header {

0 commit comments

Comments
 (0)