| 148 |
lars |
1 |
Zepto(function($) {
|
|
|
2 |
var $leftPanel = $('.left-panel');
|
|
|
3 |
var $frameContainer = $('.frames-container');
|
|
|
4 |
var $appFramesTab = $('#application-frames-tab');
|
|
|
5 |
var $allFramesTab = $('#all-frames-tab');
|
|
|
6 |
var $container = $('.details-container');
|
|
|
7 |
var $activeLine = $frameContainer.find('.frame.active');
|
|
|
8 |
var $activeFrame = $container.find('.frame-code.active');
|
|
|
9 |
var $ajaxEditors = $('.editor-link[data-ajax]');
|
|
|
10 |
var $header = $('header');
|
|
|
11 |
|
|
|
12 |
$header.on('mouseenter', function () {
|
|
|
13 |
if ($header.find('.exception').height() >= 145) {
|
|
|
14 |
$header.addClass('header-expand');
|
|
|
15 |
}
|
|
|
16 |
});
|
|
|
17 |
$header.on('mouseleave', function () {
|
|
|
18 |
$header.removeClass('header-expand');
|
|
|
19 |
});
|
|
|
20 |
|
|
|
21 |
/*
|
|
|
22 |
* add prettyprint classes to our current active codeblock
|
|
|
23 |
* run prettyPrint() to highlight the active code
|
|
|
24 |
* scroll to the line when prettyprint is done
|
|
|
25 |
* highlight the current line
|
|
|
26 |
*/
|
|
|
27 |
var renderCurrentCodeblock = function(id) {
|
|
|
28 |
Prism.highlightAll();
|
|
|
29 |
highlightCurrentLine();
|
|
|
30 |
}
|
|
|
31 |
|
|
|
32 |
/*
|
|
|
33 |
* Highlight the active and neighboring lines for the current frame
|
|
|
34 |
* Adjust the offset to make sure that line is veritcally centered
|
|
|
35 |
*/
|
|
|
36 |
|
|
|
37 |
var highlightCurrentLine = function() {
|
|
|
38 |
// We show more code than needed, purely for proper syntax highlighting
|
|
|
39 |
// Let’s hide a big chunk of that code and then scroll the remaining block
|
|
|
40 |
$activeFrame.find('.code-block').first().css({
|
|
|
41 |
maxHeight: 345,
|
|
|
42 |
overflow: 'hidden',
|
|
|
43 |
});
|
|
|
44 |
|
|
|
45 |
var line = $activeFrame.find('.code-block .line-highlight').first()[0];
|
|
|
46 |
line.scrollIntoView();
|
|
|
47 |
line.parentElement.scrollTop -= 180;
|
|
|
48 |
|
|
|
49 |
$container.scrollTop(0);
|
|
|
50 |
}
|
|
|
51 |
|
|
|
52 |
/*
|
|
|
53 |
* click handler for loading codeblocks
|
|
|
54 |
*/
|
|
|
55 |
|
|
|
56 |
$frameContainer.on('click', '.frame', function() {
|
|
|
57 |
|
|
|
58 |
var $this = $(this);
|
|
|
59 |
var id = /frame\-line\-([\d]*)/.exec($this.attr('id'))[1];
|
|
|
60 |
var $codeFrame = $('#frame-code-' + id);
|
|
|
61 |
|
|
|
62 |
if ($codeFrame) {
|
|
|
63 |
|
|
|
64 |
$activeLine.removeClass('active');
|
|
|
65 |
$activeFrame.removeClass('active');
|
|
|
66 |
|
|
|
67 |
$this.addClass('active');
|
|
|
68 |
$codeFrame.addClass('active');
|
|
|
69 |
|
|
|
70 |
$activeLine = $this;
|
|
|
71 |
$activeFrame = $codeFrame;
|
|
|
72 |
|
|
|
73 |
renderCurrentCodeblock(id);
|
|
|
74 |
|
|
|
75 |
}
|
|
|
76 |
|
|
|
77 |
});
|
|
|
78 |
|
|
|
79 |
var clipboard = new Clipboard('.clipboard');
|
|
|
80 |
var showTooltip = function(elem, msg) {
|
|
|
81 |
elem.classList.add('tooltipped', 'tooltipped-s');
|
|
|
82 |
elem.setAttribute('aria-label', msg);
|
|
|
83 |
};
|
|
|
84 |
|
|
|
85 |
clipboard.on('success', function(e) {
|
|
|
86 |
e.clearSelection();
|
|
|
87 |
|
|
|
88 |
showTooltip(e.trigger, 'Copied!');
|
|
|
89 |
});
|
|
|
90 |
|
|
|
91 |
clipboard.on('error', function(e) {
|
|
|
92 |
showTooltip(e.trigger, fallbackMessage(e.action));
|
|
|
93 |
});
|
|
|
94 |
|
|
|
95 |
var btn = document.querySelector('.clipboard');
|
|
|
96 |
|
|
|
97 |
btn.addEventListener('mouseleave', function(e) {
|
|
|
98 |
e.currentTarget.classList.remove('tooltipped', 'tooltipped-s');
|
|
|
99 |
e.currentTarget.removeAttribute('aria-label');
|
|
|
100 |
});
|
|
|
101 |
|
|
|
102 |
function fallbackMessage(action) {
|
|
|
103 |
var actionMsg = '';
|
|
|
104 |
var actionKey = (action === 'cut' ? 'X' : 'C');
|
|
|
105 |
|
|
|
106 |
if (/Mac/i.test(navigator.userAgent)) {
|
|
|
107 |
actionMsg = 'Press ⌘-' + actionKey + ' to ' + action;
|
|
|
108 |
} else {
|
|
|
109 |
actionMsg = 'Press Ctrl-' + actionKey + ' to ' + action;
|
|
|
110 |
}
|
|
|
111 |
|
|
|
112 |
return actionMsg;
|
|
|
113 |
}
|
|
|
114 |
|
|
|
115 |
function scrollIntoView($node, $parent) {
|
|
|
116 |
var nodeOffset = $node.offset();
|
|
|
117 |
var nodeTop = nodeOffset.top;
|
|
|
118 |
var nodeBottom = nodeTop + nodeOffset.height;
|
|
|
119 |
var parentScrollTop = $parent.scrollTop();
|
|
|
120 |
var parentHeight = $parent.height();
|
|
|
121 |
|
|
|
122 |
if (nodeTop < 0) {
|
|
|
123 |
$parent.scrollTop(parentScrollTop + nodeTop);
|
|
|
124 |
} else if (nodeBottom > parentHeight) {
|
|
|
125 |
$parent.scrollTop(parentScrollTop + nodeBottom - parentHeight);
|
|
|
126 |
}
|
|
|
127 |
}
|
|
|
128 |
|
|
|
129 |
$(document).on('keydown', function(e) {
|
|
|
130 |
var applicationFrames = $frameContainer.hasClass('frames-container-application'),
|
|
|
131 |
frameClass = applicationFrames ? '.frame.frame-application' : '.frame';
|
|
|
132 |
|
|
|
133 |
if(e.ctrlKey || e.which === 74 || e.which === 75) {
|
|
|
134 |
// CTRL+Arrow-UP/k and Arrow-Down/j support:
|
|
|
135 |
// 1) select the next/prev element
|
|
|
136 |
// 2) make sure the newly selected element is within the view-scope
|
|
|
137 |
// 3) focus the (right) container, so arrow-up/down (without ctrl) scroll the details
|
|
|
138 |
if (e.which === 38 /* arrow up */ || e.which === 75 /* k */) {
|
|
|
139 |
$activeLine.prev(frameClass).click();
|
|
|
140 |
scrollIntoView($activeLine, $leftPanel);
|
|
|
141 |
$container.focus();
|
|
|
142 |
e.preventDefault();
|
|
|
143 |
} else if (e.which === 40 /* arrow down */ || e.which === 74 /* j */) {
|
|
|
144 |
$activeLine.next(frameClass).click();
|
|
|
145 |
scrollIntoView($activeLine, $leftPanel);
|
|
|
146 |
$container.focus();
|
|
|
147 |
e.preventDefault();
|
|
|
148 |
}
|
|
|
149 |
} else if (e.which == 78 /* n */) {
|
|
|
150 |
if ($appFramesTab.length) {
|
|
|
151 |
setActiveFramesTab($('.frames-tab:not(.frames-tab-active)'));
|
|
|
152 |
}
|
|
|
153 |
}
|
|
|
154 |
});
|
|
|
155 |
|
|
|
156 |
// Render late enough for highlightCurrentLine to be ready
|
|
|
157 |
renderCurrentCodeblock();
|
|
|
158 |
|
|
|
159 |
// Avoid to quit the page with some protocol (e.g. IntelliJ Platform REST API)
|
|
|
160 |
$ajaxEditors.on('click', function(e){
|
|
|
161 |
e.preventDefault();
|
|
|
162 |
$.get(this.href);
|
|
|
163 |
});
|
|
|
164 |
|
|
|
165 |
// Symfony VarDumper: Close the by default expanded objects
|
|
|
166 |
$('.sf-dump-expanded')
|
|
|
167 |
.removeClass('sf-dump-expanded')
|
|
|
168 |
.addClass('sf-dump-compact');
|
|
|
169 |
$('.sf-dump-toggle span').html('▶');
|
|
|
170 |
|
|
|
171 |
// Make the given frames-tab active
|
|
|
172 |
function setActiveFramesTab($tab) {
|
|
|
173 |
$tab.addClass('frames-tab-active');
|
|
|
174 |
|
|
|
175 |
if ($tab.attr('id') == 'application-frames-tab') {
|
|
|
176 |
$frameContainer.addClass('frames-container-application');
|
|
|
177 |
$allFramesTab.removeClass('frames-tab-active');
|
|
|
178 |
} else {
|
|
|
179 |
$frameContainer.removeClass('frames-container-application');
|
|
|
180 |
$appFramesTab.removeClass('frames-tab-active');
|
|
|
181 |
}
|
|
|
182 |
}
|
|
|
183 |
|
|
|
184 |
$('a.frames-tab').on('click', function(e) {
|
|
|
185 |
e.preventDefault();
|
|
|
186 |
setActiveFramesTab($(this));
|
|
|
187 |
});
|
|
|
188 |
});
|