Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(309)

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/elements/ElementsBreadcrumbs.js

Issue 2466123002: DevTools: reformat front-end code to match chromium style. (Closed)
Patch Set: all done Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4
5 /** 4 /**
6 * @constructor 5 * @unrestricted
7 * @extends {WebInspector.HBox}
8 */ 6 */
9 WebInspector.ElementsBreadcrumbs = function() 7 WebInspector.ElementsBreadcrumbs = class extends WebInspector.HBox {
10 { 8 constructor() {
11 WebInspector.HBox.call(this, true); 9 super(true);
12 this.registerRequiredCSS("elements/breadcrumbs.css"); 10 this.registerRequiredCSS('elements/breadcrumbs.css');
13 11
14 this.crumbsElement = this.contentElement.createChild("div", "crumbs"); 12 this.crumbsElement = this.contentElement.createChild('div', 'crumbs');
15 this.crumbsElement.addEventListener("mousemove", this._mouseMovedInCrumbs.bi nd(this), false); 13 this.crumbsElement.addEventListener('mousemove', this._mouseMovedInCrumbs.bi nd(this), false);
16 this.crumbsElement.addEventListener("mouseleave", this._mouseMovedOutOfCrumb s.bind(this), false); 14 this.crumbsElement.addEventListener('mouseleave', this._mouseMovedOutOfCrumb s.bind(this), false);
17 this._nodeSymbol = Symbol("node"); 15 this._nodeSymbol = Symbol('node');
16 }
17
18 /**
19 * @override
20 */
21 wasShown() {
22 this.update();
23 }
24
25 /**
26 * @param {!Array.<!WebInspector.DOMNode>} nodes
27 */
28 updateNodes(nodes) {
29 if (!nodes.length)
30 return;
31
32 var crumbs = this.crumbsElement;
33 for (var crumb = crumbs.firstChild; crumb; crumb = crumb.nextSibling) {
34 if (nodes.indexOf(crumb[this._nodeSymbol]) !== -1) {
35 this.update(true);
36 return;
37 }
38 }
39 }
40
41 /**
42 * @param {?WebInspector.DOMNode} node
43 */
44 setSelectedNode(node) {
45 this._currentDOMNode = node;
46 this.update();
47 }
48
49 _mouseMovedInCrumbs(event) {
50 var nodeUnderMouse = event.target;
51 var crumbElement = nodeUnderMouse.enclosingNodeOrSelfWithClass('crumb');
52 var node = /** @type {?WebInspector.DOMNode} */ (crumbElement ? crumbElement [this._nodeSymbol] : null);
53 if (node)
54 node.highlight();
55 }
56
57 _mouseMovedOutOfCrumbs(event) {
58 if (this._currentDOMNode)
59 WebInspector.DOMModel.hideDOMNodeHighlight();
60 }
61
62 /**
63 * @param {boolean=} force
64 */
65 update(force) {
66 if (!this.isShowing())
67 return;
68
69 var currentDOMNode = this._currentDOMNode;
70 var crumbs = this.crumbsElement;
71
72 var handled = false;
73 var crumb = crumbs.firstChild;
74 while (crumb) {
75 if (crumb[this._nodeSymbol] === currentDOMNode) {
76 crumb.classList.add('selected');
77 handled = true;
78 } else {
79 crumb.classList.remove('selected');
80 }
81
82 crumb = crumb.nextSibling;
83 }
84
85 if (handled && !force) {
86 // We don't need to rebuild the crumbs, but we need to adjust sizes
87 // to reflect the new focused or root node.
88 this.updateSizes();
89 return;
90 }
91
92 crumbs.removeChildren();
93
94 var panel = this;
95
96 /**
97 * @param {!Event} event
98 * @this {WebInspector.ElementsBreadcrumbs}
99 */
100 function selectCrumb(event) {
101 event.preventDefault();
102 var crumb = /** @type {!Element} */ (event.currentTarget);
103 if (!crumb.classList.contains('collapsed')) {
104 this.dispatchEventToListeners(WebInspector.ElementsBreadcrumbs.Events.No deSelected, crumb[this._nodeSymbol]);
105 return;
106 }
107
108 // Clicking a collapsed crumb will expose the hidden crumbs.
109 if (crumb === panel.crumbsElement.firstChild) {
110 // If the focused crumb is the first child, pick the farthest crumb
111 // that is still hidden. This allows the user to expose every crumb.
112 var currentCrumb = crumb;
113 while (currentCrumb) {
114 var hidden = currentCrumb.classList.contains('hidden');
115 var collapsed = currentCrumb.classList.contains('collapsed');
116 if (!hidden && !collapsed)
117 break;
118 crumb = currentCrumb;
119 currentCrumb = currentCrumb.nextSiblingElement;
120 }
121 }
122
123 this.updateSizes(crumb);
124 }
125
126 var boundSelectCrumb = selectCrumb.bind(this);
127 for (var current = currentDOMNode; current; current = current.parentNode) {
128 if (current.nodeType() === Node.DOCUMENT_NODE)
129 continue;
130
131 crumb = createElementWithClass('span', 'crumb');
132 crumb[this._nodeSymbol] = current;
133 crumb.addEventListener('mousedown', boundSelectCrumb, false);
134
135 var crumbTitle = '';
136 switch (current.nodeType()) {
137 case Node.ELEMENT_NODE:
138 if (current.pseudoType())
139 crumbTitle = '::' + current.pseudoType();
140 else
141 WebInspector.DOMPresentationUtils.decorateNodeLabel(current, crumb);
142 break;
143
144 case Node.TEXT_NODE:
145 crumbTitle = WebInspector.UIString('(text)');
146 break;
147
148 case Node.COMMENT_NODE:
149 crumbTitle = '<!-->';
150 break;
151
152 case Node.DOCUMENT_TYPE_NODE:
153 crumbTitle = '<!DOCTYPE>';
154 break;
155
156 case Node.DOCUMENT_FRAGMENT_NODE:
157 crumbTitle = current.shadowRootType() ? '#shadow-root' : current.nodeN ameInCorrectCase();
158 break;
159
160 default:
161 crumbTitle = current.nodeNameInCorrectCase();
162 }
163
164 if (!crumb.childNodes.length) {
165 var nameElement = createElement('span');
166 nameElement.textContent = crumbTitle;
167 crumb.appendChild(nameElement);
168 crumb.title = crumbTitle;
169 }
170
171 if (current === currentDOMNode)
172 crumb.classList.add('selected');
173 crumbs.insertBefore(crumb, crumbs.firstChild);
174 }
175
176 this.updateSizes();
177 }
178
179 /**
180 * @param {!Element=} focusedCrumb
181 */
182 updateSizes(focusedCrumb) {
183 if (!this.isShowing())
184 return;
185
186 var crumbs = this.crumbsElement;
187 if (!crumbs.firstChild)
188 return;
189
190 var selectedIndex = 0;
191 var focusedIndex = 0;
192 var selectedCrumb;
193
194 // Reset crumb styles.
195 for (var i = 0; i < crumbs.childNodes.length; ++i) {
196 var crumb = crumbs.children[i];
197 // Find the selected crumb and index.
198 if (!selectedCrumb && crumb.classList.contains('selected')) {
199 selectedCrumb = crumb;
200 selectedIndex = i;
201 }
202
203 // Find the focused crumb index.
204 if (crumb === focusedCrumb)
205 focusedIndex = i;
206
207 crumb.classList.remove('compact', 'collapsed', 'hidden');
208 }
209
210 // Layout 1: Measure total and normal crumb sizes
211 var contentElementWidth = this.contentElement.offsetWidth;
212 var normalSizes = [];
213 for (var i = 0; i < crumbs.childNodes.length; ++i) {
214 var crumb = crumbs.childNodes[i];
215 normalSizes[i] = crumb.offsetWidth;
216 }
217
218 // Layout 2: Measure collapsed crumb sizes
219 var compactSizes = [];
220 for (var i = 0; i < crumbs.childNodes.length; ++i) {
221 var crumb = crumbs.childNodes[i];
222 crumb.classList.add('compact');
223 }
224 for (var i = 0; i < crumbs.childNodes.length; ++i) {
225 var crumb = crumbs.childNodes[i];
226 compactSizes[i] = crumb.offsetWidth;
227 }
228
229 // Layout 3: Measure collapsed crumb size
230 crumbs.firstChild.classList.add('collapsed');
231 var collapsedSize = crumbs.firstChild.offsetWidth;
232
233 // Clean up.
234 for (var i = 0; i < crumbs.childNodes.length; ++i) {
235 var crumb = crumbs.childNodes[i];
236 crumb.classList.remove('compact', 'collapsed');
237 }
238
239 function crumbsAreSmallerThanContainer() {
240 var totalSize = 0;
241 for (var i = 0; i < crumbs.childNodes.length; ++i) {
242 var crumb = crumbs.childNodes[i];
243 if (crumb.classList.contains('hidden'))
244 continue;
245 if (crumb.classList.contains('collapsed')) {
246 totalSize += collapsedSize;
247 continue;
248 }
249 totalSize += crumb.classList.contains('compact') ? compactSizes[i] : nor malSizes[i];
250 }
251 const rightPadding = 10;
252 return totalSize + rightPadding < contentElementWidth;
253 }
254
255 if (crumbsAreSmallerThanContainer())
256 return; // No need to compact the crumbs, they all fit at full size.
257
258 var BothSides = 0;
259 var AncestorSide = -1;
260 var ChildSide = 1;
261
262 /**
263 * @param {function(!Element)} shrinkingFunction
264 * @param {number} direction
265 */
266 function makeCrumbsSmaller(shrinkingFunction, direction) {
267 var significantCrumb = focusedCrumb || selectedCrumb;
268 var significantIndex = significantCrumb === selectedCrumb ? selectedIndex : focusedIndex;
269
270 function shrinkCrumbAtIndex(index) {
271 var shrinkCrumb = crumbs.children[index];
272 if (shrinkCrumb && shrinkCrumb !== significantCrumb)
273 shrinkingFunction(shrinkCrumb);
274 if (crumbsAreSmallerThanContainer())
275 return true; // No need to compact the crumbs more.
276 return false;
277 }
278
279 // Shrink crumbs one at a time by applying the shrinkingFunction until the crumbs
280 // fit in the container or we run out of crumbs to shrink.
281 if (direction) {
282 // Crumbs are shrunk on only one side (based on direction) of the signif cant crumb.
283 var index = (direction > 0 ? 0 : crumbs.childNodes.length - 1);
284 while (index !== significantIndex) {
285 if (shrinkCrumbAtIndex(index))
286 return true;
287 index += (direction > 0 ? 1 : -1);
288 }
289 } else {
290 // Crumbs are shrunk in order of descending distance from the signifcant crumb,
291 // with a tie going to child crumbs.
292 var startIndex = 0;
293 var endIndex = crumbs.childNodes.length - 1;
294 while (startIndex !== significantIndex || endIndex !== significantIndex) {
295 var startDistance = significantIndex - startIndex;
296 var endDistance = endIndex - significantIndex;
297 if (startDistance >= endDistance)
298 var index = startIndex++;
299 else
300 var index = endIndex--;
301 if (shrinkCrumbAtIndex(index))
302 return true;
303 }
304 }
305
306 // We are not small enough yet, return false so the caller knows.
307 return false;
308 }
309
310 function coalesceCollapsedCrumbs() {
311 var crumb = crumbs.firstChild;
312 var collapsedRun = false;
313 var newStartNeeded = false;
314 var newEndNeeded = false;
315 while (crumb) {
316 var hidden = crumb.classList.contains('hidden');
317 if (!hidden) {
318 var collapsed = crumb.classList.contains('collapsed');
319 if (collapsedRun && collapsed) {
320 crumb.classList.add('hidden');
321 crumb.classList.remove('compact');
322 crumb.classList.remove('collapsed');
323
324 if (crumb.classList.contains('start')) {
325 crumb.classList.remove('start');
326 newStartNeeded = true;
327 }
328
329 if (crumb.classList.contains('end')) {
330 crumb.classList.remove('end');
331 newEndNeeded = true;
332 }
333
334 continue;
335 }
336
337 collapsedRun = collapsed;
338
339 if (newEndNeeded) {
340 newEndNeeded = false;
341 crumb.classList.add('end');
342 }
343 } else {
344 collapsedRun = true;
345 }
346 crumb = crumb.nextSibling;
347 }
348
349 if (newStartNeeded) {
350 crumb = crumbs.lastChild;
351 while (crumb) {
352 if (!crumb.classList.contains('hidden')) {
353 crumb.classList.add('start');
354 break;
355 }
356 crumb = crumb.previousSibling;
357 }
358 }
359 }
360
361 /**
362 * @param {!Element} crumb
363 */
364 function compact(crumb) {
365 if (crumb.classList.contains('hidden'))
366 return;
367 crumb.classList.add('compact');
368 }
369
370 /**
371 * @param {!Element} crumb
372 * @param {boolean=} dontCoalesce
373 */
374 function collapse(crumb, dontCoalesce) {
375 if (crumb.classList.contains('hidden'))
376 return;
377 crumb.classList.add('collapsed');
378 crumb.classList.remove('compact');
379 if (!dontCoalesce)
380 coalesceCollapsedCrumbs();
381 }
382
383 if (!focusedCrumb) {
384 // When not focused on a crumb we can be biased and collapse less importan t
385 // crumbs that the user might not care much about.
386
387 // Compact child crumbs.
388 if (makeCrumbsSmaller(compact, ChildSide))
389 return;
390
391 // Collapse child crumbs.
392 if (makeCrumbsSmaller(collapse, ChildSide))
393 return;
394 }
395
396 // Compact ancestor crumbs, or from both sides if focused.
397 if (makeCrumbsSmaller(compact, focusedCrumb ? BothSides : AncestorSide))
398 return;
399
400 // Collapse ancestor crumbs, or from both sides if focused.
401 if (makeCrumbsSmaller(collapse, focusedCrumb ? BothSides : AncestorSide))
402 return;
403
404 if (!selectedCrumb)
405 return;
406
407 // Compact the selected crumb.
408 compact(selectedCrumb);
409 if (crumbsAreSmallerThanContainer())
410 return;
411
412 // Collapse the selected crumb as a last resort. Pass true to prevent coales cing.
413 collapse(selectedCrumb, true);
414 }
18 }; 415 };
19 416
20 /** @enum {symbol} */ 417 /** @enum {symbol} */
21 WebInspector.ElementsBreadcrumbs.Events = { 418 WebInspector.ElementsBreadcrumbs.Events = {
22 NodeSelected: Symbol("NodeSelected") 419 NodeSelected: Symbol('NodeSelected')
23 }; 420 };
24
25 WebInspector.ElementsBreadcrumbs.prototype = {
26 wasShown: function()
27 {
28 this.update();
29 },
30
31 /**
32 * @param {!Array.<!WebInspector.DOMNode>} nodes
33 */
34 updateNodes: function(nodes)
35 {
36 if (!nodes.length)
37 return;
38
39 var crumbs = this.crumbsElement;
40 for (var crumb = crumbs.firstChild; crumb; crumb = crumb.nextSibling) {
41 if (nodes.indexOf(crumb[this._nodeSymbol]) !== -1) {
42 this.update(true);
43 return;
44 }
45 }
46 },
47
48 /**
49 * @param {?WebInspector.DOMNode} node
50 */
51 setSelectedNode: function(node)
52 {
53 this._currentDOMNode = node;
54 this.update();
55 },
56
57 _mouseMovedInCrumbs: function(event)
58 {
59 var nodeUnderMouse = event.target;
60 var crumbElement = nodeUnderMouse.enclosingNodeOrSelfWithClass("crumb");
61 var node = /** @type {?WebInspector.DOMNode} */ (crumbElement ? crumbEle ment[this._nodeSymbol] : null);
62 if (node)
63 node.highlight();
64 },
65
66 _mouseMovedOutOfCrumbs: function(event)
67 {
68 if (this._currentDOMNode)
69 WebInspector.DOMModel.hideDOMNodeHighlight();
70 },
71
72 /**
73 * @param {boolean=} force
74 */
75 update: function(force)
76 {
77 if (!this.isShowing())
78 return;
79
80 var currentDOMNode = this._currentDOMNode;
81 var crumbs = this.crumbsElement;
82
83 var handled = false;
84 var crumb = crumbs.firstChild;
85 while (crumb) {
86 if (crumb[this._nodeSymbol] === currentDOMNode) {
87 crumb.classList.add("selected");
88 handled = true;
89 } else {
90 crumb.classList.remove("selected");
91 }
92
93 crumb = crumb.nextSibling;
94 }
95
96 if (handled && !force) {
97 // We don't need to rebuild the crumbs, but we need to adjust sizes
98 // to reflect the new focused or root node.
99 this.updateSizes();
100 return;
101 }
102
103 crumbs.removeChildren();
104
105 var panel = this;
106
107 /**
108 * @param {!Event} event
109 * @this {WebInspector.ElementsBreadcrumbs}
110 */
111 function selectCrumb(event)
112 {
113 event.preventDefault();
114 var crumb = /** @type {!Element} */ (event.currentTarget);
115 if (!crumb.classList.contains("collapsed")) {
116 this.dispatchEventToListeners(WebInspector.ElementsBreadcrumbs.E vents.NodeSelected, crumb[this._nodeSymbol]);
117 return;
118 }
119
120 // Clicking a collapsed crumb will expose the hidden crumbs.
121 if (crumb === panel.crumbsElement.firstChild) {
122 // If the focused crumb is the first child, pick the farthest cr umb
123 // that is still hidden. This allows the user to expose every cr umb.
124 var currentCrumb = crumb;
125 while (currentCrumb) {
126 var hidden = currentCrumb.classList.contains("hidden");
127 var collapsed = currentCrumb.classList.contains("collapsed") ;
128 if (!hidden && !collapsed)
129 break;
130 crumb = currentCrumb;
131 currentCrumb = currentCrumb.nextSiblingElement;
132 }
133 }
134
135 this.updateSizes(crumb);
136 }
137
138 var boundSelectCrumb = selectCrumb.bind(this);
139 for (var current = currentDOMNode; current; current = current.parentNode ) {
140 if (current.nodeType() === Node.DOCUMENT_NODE)
141 continue;
142
143 crumb = createElementWithClass("span", "crumb");
144 crumb[this._nodeSymbol] = current;
145 crumb.addEventListener("mousedown", boundSelectCrumb, false);
146
147 var crumbTitle = "";
148 switch (current.nodeType()) {
149 case Node.ELEMENT_NODE:
150 if (current.pseudoType())
151 crumbTitle = "::" + current.pseudoType();
152 else
153 WebInspector.DOMPresentationUtils.decorateNodeLabel(current, crumb);
154 break;
155
156 case Node.TEXT_NODE:
157 crumbTitle = WebInspector.UIString("(text)");
158 break;
159
160 case Node.COMMENT_NODE:
161 crumbTitle = "<!-->";
162 break;
163
164 case Node.DOCUMENT_TYPE_NODE:
165 crumbTitle = "<!DOCTYPE>";
166 break;
167
168 case Node.DOCUMENT_FRAGMENT_NODE:
169 crumbTitle = current.shadowRootType() ? "#shadow-root" : current .nodeNameInCorrectCase();
170 break;
171
172 default:
173 crumbTitle = current.nodeNameInCorrectCase();
174 }
175
176 if (!crumb.childNodes.length) {
177 var nameElement = createElement("span");
178 nameElement.textContent = crumbTitle;
179 crumb.appendChild(nameElement);
180 crumb.title = crumbTitle;
181 }
182
183 if (current === currentDOMNode)
184 crumb.classList.add("selected");
185 crumbs.insertBefore(crumb, crumbs.firstChild);
186 }
187
188 this.updateSizes();
189 },
190
191 /**
192 * @param {!Element=} focusedCrumb
193 */
194 updateSizes: function(focusedCrumb)
195 {
196 if (!this.isShowing())
197 return;
198
199 var crumbs = this.crumbsElement;
200 if (!crumbs.firstChild)
201 return;
202
203 var selectedIndex = 0;
204 var focusedIndex = 0;
205 var selectedCrumb;
206
207 // Reset crumb styles.
208 for (var i = 0; i < crumbs.childNodes.length; ++i) {
209 var crumb = crumbs.children[i];
210 // Find the selected crumb and index.
211 if (!selectedCrumb && crumb.classList.contains("selected")) {
212 selectedCrumb = crumb;
213 selectedIndex = i;
214 }
215
216 // Find the focused crumb index.
217 if (crumb === focusedCrumb)
218 focusedIndex = i;
219
220 crumb.classList.remove("compact", "collapsed", "hidden");
221 }
222
223 // Layout 1: Measure total and normal crumb sizes
224 var contentElementWidth = this.contentElement.offsetWidth;
225 var normalSizes = [];
226 for (var i = 0; i < crumbs.childNodes.length; ++i) {
227 var crumb = crumbs.childNodes[i];
228 normalSizes[i] = crumb.offsetWidth;
229 }
230
231 // Layout 2: Measure collapsed crumb sizes
232 var compactSizes = [];
233 for (var i = 0; i < crumbs.childNodes.length; ++i) {
234 var crumb = crumbs.childNodes[i];
235 crumb.classList.add("compact");
236 }
237 for (var i = 0; i < crumbs.childNodes.length; ++i) {
238 var crumb = crumbs.childNodes[i];
239 compactSizes[i] = crumb.offsetWidth;
240 }
241
242 // Layout 3: Measure collapsed crumb size
243 crumbs.firstChild.classList.add("collapsed");
244 var collapsedSize = crumbs.firstChild.offsetWidth;
245
246 // Clean up.
247 for (var i = 0; i < crumbs.childNodes.length; ++i) {
248 var crumb = crumbs.childNodes[i];
249 crumb.classList.remove("compact", "collapsed");
250 }
251
252 function crumbsAreSmallerThanContainer()
253 {
254 var totalSize = 0;
255 for (var i = 0; i < crumbs.childNodes.length; ++i) {
256 var crumb = crumbs.childNodes[i];
257 if (crumb.classList.contains("hidden"))
258 continue;
259 if (crumb.classList.contains("collapsed")) {
260 totalSize += collapsedSize;
261 continue;
262 }
263 totalSize += crumb.classList.contains("compact") ? compactSizes[ i] : normalSizes[i];
264 }
265 const rightPadding = 10;
266 return totalSize + rightPadding < contentElementWidth;
267 }
268
269 if (crumbsAreSmallerThanContainer())
270 return; // No need to compact the crumbs, they all fit at full size.
271
272 var BothSides = 0;
273 var AncestorSide = -1;
274 var ChildSide = 1;
275
276 /**
277 * @param {function(!Element)} shrinkingFunction
278 * @param {number} direction
279 */
280 function makeCrumbsSmaller(shrinkingFunction, direction)
281 {
282 var significantCrumb = focusedCrumb || selectedCrumb;
283 var significantIndex = significantCrumb === selectedCrumb ? selected Index : focusedIndex;
284
285 function shrinkCrumbAtIndex(index)
286 {
287 var shrinkCrumb = crumbs.children[index];
288 if (shrinkCrumb && shrinkCrumb !== significantCrumb)
289 shrinkingFunction(shrinkCrumb);
290 if (crumbsAreSmallerThanContainer())
291 return true; // No need to compact the crumbs more.
292 return false;
293 }
294
295 // Shrink crumbs one at a time by applying the shrinkingFunction unt il the crumbs
296 // fit in the container or we run out of crumbs to shrink.
297 if (direction) {
298 // Crumbs are shrunk on only one side (based on direction) of th e signifcant crumb.
299 var index = (direction > 0 ? 0 : crumbs.childNodes.length - 1);
300 while (index !== significantIndex) {
301 if (shrinkCrumbAtIndex(index))
302 return true;
303 index += (direction > 0 ? 1 : -1);
304 }
305 } else {
306 // Crumbs are shrunk in order of descending distance from the si gnifcant crumb,
307 // with a tie going to child crumbs.
308 var startIndex = 0;
309 var endIndex = crumbs.childNodes.length - 1;
310 while (startIndex !== significantIndex || endIndex !== significa ntIndex) {
311 var startDistance = significantIndex - startIndex;
312 var endDistance = endIndex - significantIndex;
313 if (startDistance >= endDistance)
314 var index = startIndex++;
315 else
316 var index = endIndex--;
317 if (shrinkCrumbAtIndex(index))
318 return true;
319 }
320 }
321
322 // We are not small enough yet, return false so the caller knows.
323 return false;
324 }
325
326 function coalesceCollapsedCrumbs()
327 {
328 var crumb = crumbs.firstChild;
329 var collapsedRun = false;
330 var newStartNeeded = false;
331 var newEndNeeded = false;
332 while (crumb) {
333 var hidden = crumb.classList.contains("hidden");
334 if (!hidden) {
335 var collapsed = crumb.classList.contains("collapsed");
336 if (collapsedRun && collapsed) {
337 crumb.classList.add("hidden");
338 crumb.classList.remove("compact");
339 crumb.classList.remove("collapsed");
340
341 if (crumb.classList.contains("start")) {
342 crumb.classList.remove("start");
343 newStartNeeded = true;
344 }
345
346 if (crumb.classList.contains("end")) {
347 crumb.classList.remove("end");
348 newEndNeeded = true;
349 }
350
351 continue;
352 }
353
354 collapsedRun = collapsed;
355
356 if (newEndNeeded) {
357 newEndNeeded = false;
358 crumb.classList.add("end");
359 }
360 } else {
361 collapsedRun = true;
362 }
363 crumb = crumb.nextSibling;
364 }
365
366 if (newStartNeeded) {
367 crumb = crumbs.lastChild;
368 while (crumb) {
369 if (!crumb.classList.contains("hidden")) {
370 crumb.classList.add("start");
371 break;
372 }
373 crumb = crumb.previousSibling;
374 }
375 }
376 }
377
378 /**
379 * @param {!Element} crumb
380 */
381 function compact(crumb)
382 {
383 if (crumb.classList.contains("hidden"))
384 return;
385 crumb.classList.add("compact");
386 }
387
388 /**
389 * @param {!Element} crumb
390 * @param {boolean=} dontCoalesce
391 */
392 function collapse(crumb, dontCoalesce)
393 {
394 if (crumb.classList.contains("hidden"))
395 return;
396 crumb.classList.add("collapsed");
397 crumb.classList.remove("compact");
398 if (!dontCoalesce)
399 coalesceCollapsedCrumbs();
400 }
401
402 if (!focusedCrumb) {
403 // When not focused on a crumb we can be biased and collapse less im portant
404 // crumbs that the user might not care much about.
405
406 // Compact child crumbs.
407 if (makeCrumbsSmaller(compact, ChildSide))
408 return;
409
410 // Collapse child crumbs.
411 if (makeCrumbsSmaller(collapse, ChildSide))
412 return;
413 }
414
415 // Compact ancestor crumbs, or from both sides if focused.
416 if (makeCrumbsSmaller(compact, focusedCrumb ? BothSides : AncestorSide))
417 return;
418
419 // Collapse ancestor crumbs, or from both sides if focused.
420 if (makeCrumbsSmaller(collapse, focusedCrumb ? BothSides : AncestorSide) )
421 return;
422
423 if (!selectedCrumb)
424 return;
425
426 // Compact the selected crumb.
427 compact(selectedCrumb);
428 if (crumbsAreSmallerThanContainer())
429 return;
430
431 // Collapse the selected crumb as a last resort. Pass true to prevent co alescing.
432 collapse(selectedCrumb, true);
433 },
434
435 __proto__: WebInspector.HBox.prototype
436 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698