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

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/console/ConsoleView.js

Issue 2179123004: DevTools: fix stick to bottom in console viewport (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address comments Created 4 years, 4 months 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 /* 1 /*
2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. 2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
3 * Copyright (C) 2009 Joseph Pecoraro 3 * Copyright (C) 2009 Joseph Pecoraro
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 8 *
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 /** @type {!Array.<!WebInspector.ConsoleViewMessage>} */ 129 /** @type {!Array.<!WebInspector.ConsoleViewMessage>} */
130 this._consoleMessages = []; 130 this._consoleMessages = [];
131 this._viewMessageSymbol = Symbol("viewMessage"); 131 this._viewMessageSymbol = Symbol("viewMessage");
132 132
133 this._prompt = new WebInspector.TextPromptWithHistory(WebInspector.Execution ContextSelector.completionsForTextPromptInCurrentContext); 133 this._prompt = new WebInspector.TextPromptWithHistory(WebInspector.Execution ContextSelector.completionsForTextPromptInCurrentContext);
134 this._prompt.setSuggestBoxEnabled(true); 134 this._prompt.setSuggestBoxEnabled(true);
135 this._prompt.setAutocompletionTimeout(0); 135 this._prompt.setAutocompletionTimeout(0);
136 this._prompt.renderAsBlock(); 136 this._prompt.renderAsBlock();
137 var proxyElement = this._prompt.attach(this._promptElement); 137 var proxyElement = this._prompt.attach(this._promptElement);
138 proxyElement.addEventListener("keydown", this._promptKeyDown.bind(this), fal se); 138 proxyElement.addEventListener("keydown", this._promptKeyDown.bind(this), fal se);
139 proxyElement.addEventListener("input", this._promptInput.bind(this), false);
139 140
140 this._consoleHistorySetting = WebInspector.settings.createLocalSetting("cons oleHistory", []); 141 this._consoleHistorySetting = WebInspector.settings.createLocalSetting("cons oleHistory", []);
141 var historyData = this._consoleHistorySetting.get(); 142 var historyData = this._consoleHistorySetting.get();
142 this._prompt.setHistoryData(historyData); 143 this._prompt.setHistoryData(historyData);
143 144
144 this._consoleHistoryAutocompleteSetting = WebInspector.moduleSetting("consol eHistoryAutocomplete"); 145 this._consoleHistoryAutocompleteSetting = WebInspector.moduleSetting("consol eHistoryAutocomplete");
145 this._consoleHistoryAutocompleteSetting.addChangeListener(this._consoleHisto ryAutocompleteChanged, this); 146 this._consoleHistoryAutocompleteSetting.addChangeListener(this._consoleHisto ryAutocompleteChanged, this);
146 this._consoleHistoryAutocompleteChanged(); 147 this._consoleHistoryAutocompleteChanged();
147 148
148 this._updateFilterStatus(); 149 this._updateFilterStatus();
149 WebInspector.moduleSetting("consoleTimestampsEnabled").addChangeListener(thi s._consoleTimestampsSettingChanged, this); 150 WebInspector.moduleSetting("consoleTimestampsEnabled").addChangeListener(thi s._consoleTimestampsSettingChanged, this);
150 151
151 this._registerWithMessageSink(); 152 this._registerWithMessageSink();
152 WebInspector.targetManager.observeTargets(this); 153 WebInspector.targetManager.observeTargets(this);
153 154
154 this._initConsoleMessages(); 155 this._initConsoleMessages();
155 156
156 WebInspector.context.addFlavorChangeListener(WebInspector.ExecutionContext, this._executionContextChanged, this); 157 WebInspector.context.addFlavorChangeListener(WebInspector.ExecutionContext, this._executionContextChanged, this);
158
159 this._messagesElement.addEventListener("mousedown", this._updateStickToBotto mOnMouseDown.bind(this), false);
160 this._messagesElement.addEventListener("mousewheel", this._updateStickToBott omOnMouseWheel.bind(this), false);
161 this._messagesElement.addEventListener("mouseup", this._updateStickToBottomO nMouseUp.bind(this), false);
162 this._messagesElement.addEventListener("mouseleave", this._updateStickToBott omOnMouseUp.bind(this), false);
163 this._messagesElement.addEventListener("keydown", this._updateStickToBottomO nKeyDown.bind(this), true);
dgozman 2016/08/05 17:36:42 false
luoe 2016/08/05 19:43:57 Done.
157 } 164 }
158 165
159 WebInspector.ConsoleView.persistedHistorySize = 300; 166 WebInspector.ConsoleView.persistedHistorySize = 300;
160 167
161 WebInspector.ConsoleView.prototype = { 168 WebInspector.ConsoleView.prototype = {
162 /** 169 /**
163 * @return {!WebInspector.SearchableView} 170 * @return {!WebInspector.SearchableView}
164 */ 171 */
165 searchableView: function() 172 searchableView: function()
166 { 173 {
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
346 if (this._promptElement === WebInspector.currentFocusElement()) 353 if (this._promptElement === WebInspector.currentFocusElement())
347 return; 354 return;
348 // Set caret position before setting focus in order to avoid scrolling 355 // Set caret position before setting focus in order to avoid scrolling
349 // by focus(). 356 // by focus().
350 this._prompt.moveCaretToEndOfPrompt(); 357 this._prompt.moveCaretToEndOfPrompt();
351 WebInspector.setCurrentFocusElement(this._promptElement); 358 WebInspector.setCurrentFocusElement(this._promptElement);
352 }, 359 },
353 360
354 restoreScrollPositions: function() 361 restoreScrollPositions: function()
355 { 362 {
356 if (this._viewport.scrolledToBottom()) 363 if (this._viewport.stickToBottom())
357 this._immediatelyScrollToBottom(); 364 this._immediatelyScrollToBottom();
358 else 365 else
359 WebInspector.Widget.prototype.restoreScrollPositions.call(this); 366 WebInspector.Widget.prototype.restoreScrollPositions.call(this);
360 }, 367 },
361 368
362 onResize: function() 369 onResize: function()
363 { 370 {
364 this._scheduleViewportRefresh(); 371 this._scheduleViewportRefresh();
365 this._hidePromptSuggestBox(); 372 this._hidePromptSuggestBox();
366 if (this._viewport.scrolledToBottom()) 373 if (this._viewport.stickToBottom())
367 this._immediatelyScrollToBottom(); 374 this._immediatelyScrollToBottom();
368 for (var i = 0; i < this._visibleViewMessages.length; ++i) 375 for (var i = 0; i < this._visibleViewMessages.length; ++i)
369 this._visibleViewMessages[i].onResize(); 376 this._visibleViewMessages[i].onResize();
370 }, 377 },
371 378
372 _hidePromptSuggestBox: function() 379 _hidePromptSuggestBox: function()
373 { 380 {
374 this._prompt.hideSuggestBox(); 381 this._prompt.hideSuggestBox();
375 this._prompt.clearAutoComplete(true); 382 this._prompt.clearAutoComplete(true);
376 }, 383 },
377 384
378 _scheduleViewportRefresh: function() 385 _scheduleViewportRefresh: function()
379 { 386 {
380 /** 387 /**
381 * @this {WebInspector.ConsoleView} 388 * @this {WebInspector.ConsoleView}
382 * @return {!Promise.<undefined>} 389 * @return {!Promise.<undefined>}
383 */ 390 */
384 function invalidateViewport() 391 function invalidateViewport()
385 { 392 {
393 if (this._muteViewportUpdates)
394 return Promise.resolve();
386 if (this._needsFullUpdate) { 395 if (this._needsFullUpdate) {
387 this._updateMessageList(); 396 this._updateMessageList();
388 delete this._needsFullUpdate; 397 delete this._needsFullUpdate;
389 } else { 398 } else {
390 this._viewport.invalidate(); 399 this._viewport.invalidate();
391 } 400 }
392 return Promise.resolve(); 401 return Promise.resolve();
393 } 402 }
403 if (this._muteViewportUpdates)
404 return;
394 this._viewportThrottler.schedule(invalidateViewport.bind(this)); 405 this._viewportThrottler.schedule(invalidateViewport.bind(this));
395 }, 406 },
396 407
397 _immediatelyScrollToBottom: function() 408 _immediatelyScrollToBottom: function()
398 { 409 {
399 // This will scroll viewport and trigger its refresh. 410 // This will scroll viewport and trigger its refresh.
411 this._viewport.setStickToBottom(true);
400 this._promptElement.scrollIntoView(true); 412 this._promptElement.scrollIntoView(true);
401 }, 413 },
402 414
403 _updateFilterStatus: function() 415 _updateFilterStatus: function()
404 { 416 {
405 this._filterStatusTextElement.textContent = WebInspector.UIString(this._ hiddenByFilterCount === 1 ? "%d message is hidden by filters." : "%d messages ar e hidden by filters.", this._hiddenByFilterCount); 417 this._filterStatusTextElement.textContent = WebInspector.UIString(this._ hiddenByFilterCount === 1 ? "%d message is hidden by filters." : "%d messages ar e hidden by filters.", this._hiddenByFilterCount);
406 this._filterStatusMessageElement.style.display = this._hiddenByFilterCou nt ? "" : "none"; 418 this._filterStatusMessageElement.style.display = this._hiddenByFilterCou nt ? "" : "none";
407 }, 419 },
408 420
409 /** 421 /**
(...skipping 587 matching lines...) Expand 10 before | Expand all | Expand 10 after
997 this._currentMatchRangeIndex = index; 1009 this._currentMatchRangeIndex = index;
998 this._searchableView.updateCurrentMatchIndex(index); 1010 this._searchableView.updateCurrentMatchIndex(index);
999 matchRange = this._regexMatchRanges[index]; 1011 matchRange = this._regexMatchRanges[index];
1000 var message = this._visibleViewMessages[matchRange.messageIndex]; 1012 var message = this._visibleViewMessages[matchRange.messageIndex];
1001 var highlightNode = message.searchHighlightNode(matchRange.matchIndex); 1013 var highlightNode = message.searchHighlightNode(matchRange.matchIndex);
1002 highlightNode.classList.add(WebInspector.highlightedCurrentSearchResultC lassName); 1014 highlightNode.classList.add(WebInspector.highlightedCurrentSearchResultC lassName);
1003 this._viewport.scrollItemIntoView(matchRange.messageIndex); 1015 this._viewport.scrollItemIntoView(matchRange.messageIndex);
1004 highlightNode.scrollIntoViewIfNeeded(); 1016 highlightNode.scrollIntoViewIfNeeded();
1005 }, 1017 },
1006 1018
1019 _updateStickToBottomOnMouseDown: function()
1020 {
1021 this._muteViewportUpdates = true;
1022 this._viewport.setStickToBottom(false);
1023 this._wasScrolledToBottom = this._messagesElement.isScrolledToBottom();
dgozman 2016/08/05 17:36:41 This we can remove.
luoe 2016/08/05 19:43:57 Done.
1024 },
1025
1026 _updateStickToBottomOnMouseUp: function()
1027 {
1028 if (!this._muteViewportUpdates)
1029 return;
1030
1031 this._muteViewportUpdates = false;
dgozman 2016/08/05 17:36:41 This goes to updateViewportState, together with sc
luoe 2016/08/05 19:43:57 Done.
1032 if (this._wasScrolledToBottom) {
1033 // Clicking the scrollbar may trigger events in the order:
1034 // mousedown > mouseup > scroll. Delay querying isScrolledToBottom
1035 // to give time for smooth scroll events to arrive. The value for
1036 // the longest timeout duration is retrieved from crbug.com/575409.
1037 setTimeout(updateViewportState.bind(this), 200);
1038 } else {
1039 // In another case, when users drag the scroll thumb to the bottom,
1040 // the viewport should stick. Checking whether the mouse is released
1041 // at the bottom of the viewport is not verifiable after an async
1042 // timeout, so we do it immediately.
1043 updateViewportState.call(this);
1044 }
1045 delete this._wasScrolledToBottom;
1046
1047 /**
1048 * @this {!WebInspector.ConsoleView}
1049 */
1050 function updateViewportState()
1051 {
1052 this._viewport.setStickToBottom(this._messagesElement.isScrolledToBo ttom());
1053 this._updateViewportStickinessForTest();
1054 }
1055 },
1056
1057 _updateViewportStickinessForTest: function()
1058 {
1059 // This method is sniffed in tests.
1060 },
1061
1062 _updateStickToBottomOnMouseWheel: function()
dgozman 2016/08/05 17:10:01 Do we handle touchpad here? Are there any other ty
luoe 2016/08/05 19:43:57 Good catch, switched from 'mousewheel' to 'wheel'.
1063 {
1064 this._updateStickToBottomOnMouseDown();
1065 this._updateStickToBottomOnMouseUp();
1066 },
1067
1068 _promptInput: function(event)
1069 {
1070 this._viewport.setStickToBottom(true);
1071 },
1072
1073 _updateStickToBottomOnKeyDown: function(event)
1074 {
1075 if (!this._prompt.isCaretInsidePrompt())
1076 return;
1077
1078 // Check for keys that should focus on prompt but do not change input.
1079 var isHomeEnd = event.key === "Home" || event.key === "End";
1080 var isArrowKey = event.key === "ArrowUp" || event.key === "ArrowRight" | | event.key === "ArrowDown" || event.key === "ArrowLeft";
1081
1082 if (isHomeEnd || isArrowKey || event.key === "PageDown")
1083 this._viewport.setStickToBottom(true);
1084 else if (event.key === "PageUp")
dgozman 2016/08/05 17:10:01 PageUp/PageDown are handled by multiline prompt -
luoe 2016/08/05 19:43:57 We can actually move this logic into promptKeyDown
1085 this._updateStickToBottomOnMouseWheel();
dgozman 2016/08/05 17:36:41 We call this for all the keys listed above.
luoe 2016/08/05 19:43:57 After manual testing, it looks like the rest of th
1086 },
1087
1007 __proto__: WebInspector.VBox.prototype 1088 __proto__: WebInspector.VBox.prototype
1008 } 1089 }
1009 1090
1010 /** 1091 /**
1011 * @constructor 1092 * @constructor
1012 * @extends {WebInspector.Object} 1093 * @extends {WebInspector.Object}
1013 * @param {!WebInspector.ConsoleView} view 1094 * @param {!WebInspector.ConsoleView} view
1014 */ 1095 */
1015 WebInspector.ConsoleViewFilter = function(view) 1096 WebInspector.ConsoleViewFilter = function(view)
1016 { 1097 {
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after
1339 return true; 1420 return true;
1340 } 1421 }
1341 return false; 1422 return false;
1342 } 1423 }
1343 } 1424 }
1344 1425
1345 /** 1426 /**
1346 * @typedef {{messageIndex: number, matchIndex: number}} 1427 * @typedef {{messageIndex: number, matchIndex: number}}
1347 */ 1428 */
1348 WebInspector.ConsoleView.RegexMatchRange; 1429 WebInspector.ConsoleView.RegexMatchRange;
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698