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

Side by Side Diff: Source/devtools/front_end/SourcesEditor.js

Issue 214793004: DevTools: Rename SourcesEditor.js to SourcesView.js (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Rebaselined Created 6 years, 9 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 | Annotate | Revision Log
« no previous file with comments | « Source/devtools/devtools.gypi ('k') | Source/devtools/front_end/SourcesPanel.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 /**
6 * @constructor
7 * @implements {WebInspector.TabbedEditorContainerDelegate}
8 * @implements {WebInspector.Searchable}
9 * @implements {WebInspector.Replaceable}
10 * @extends {WebInspector.VBox}
11 * @param {!WebInspector.Workspace} workspace
12 * @param {!WebInspector.SourcesPanel} sourcesPanel
13 */
14 WebInspector.SourcesView = function(workspace, sourcesPanel)
15 {
16 WebInspector.VBox.call(this);
17 this.registerRequiredCSS("sourcesView.css");
18 this.element.id = "sources-panel-sources-view";
19 this.setMinimumSize(50, 25);
20
21 this._workspace = workspace;
22 this._sourcesPanel = sourcesPanel;
23
24 this._searchableView = new WebInspector.SearchableView(this);
25 this._searchableView.setMinimalSearchQuerySize(0);
26 this._searchableView.show(this.element);
27
28 /** @type {!Map.<!WebInspector.UISourceCode, !WebInspector.SourceFrame>} */
29 this._sourceFramesByUISourceCode = new Map();
30
31 var tabbedEditorPlaceholderText = WebInspector.isMac() ? WebInspector.UIStri ng("Hit Cmd+O to open a file") : WebInspector.UIString("Hit Ctrl+O to open a fil e");
32 this._editorContainer = new WebInspector.TabbedEditorContainer(this, "previo uslyViewedFiles", tabbedEditorPlaceholderText);
33 this._editorContainer.show(this._searchableView.element);
34 this._editorContainer.addEventListener(WebInspector.TabbedEditorContainer.Ev ents.EditorSelected, this._editorSelected, this);
35 this._editorContainer.addEventListener(WebInspector.TabbedEditorContainer.Ev ents.EditorClosed, this._editorClosed, this);
36
37 this._historyManager = new WebInspector.EditingLocationHistoryManager(this, this.currentSourceFrame.bind(this));
38
39 this._scriptViewStatusBarItemsContainer = document.createElement("div");
40 this._scriptViewStatusBarItemsContainer.className = "inline-block";
41
42 this._scriptViewStatusBarTextContainer = document.createElement("div");
43 this._scriptViewStatusBarTextContainer.className = "hbox";
44
45 this._statusBarContainerElement = this.element.createChild("div", "sources-s tatus-bar");
46
47 /**
48 * @this {WebInspector.SourcesView}
49 * @param {!WebInspector.SourcesView.EditorAction} EditorAction
50 */
51 function appendButtonForExtension(EditorAction)
52 {
53 this._statusBarContainerElement.appendChild(EditorAction.button(this));
54 }
55 var editorActions = /** @type {!Array.<!WebInspector.SourcesView.EditorActio n>} */ (WebInspector.moduleManager.instances(WebInspector.SourcesView.EditorActi on));
56 editorActions.forEach(appendButtonForExtension.bind(this));
57
58 this._statusBarContainerElement.appendChild(this._scriptViewStatusBarItemsCo ntainer);
59 this._statusBarContainerElement.appendChild(this._scriptViewStatusBarTextCon tainer);
60
61 WebInspector.startBatchUpdate();
62 this._workspace.uiSourceCodes().forEach(this._addUISourceCode.bind(this));
63 WebInspector.endBatchUpdate();
64
65 this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeA dded, this._uiSourceCodeAdded, this);
66 this._workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeR emoved, this._uiSourceCodeRemoved, this);
67 this._workspace.addEventListener(WebInspector.Workspace.Events.ProjectWillRe set, this._projectWillReset.bind(this), this);
68
69 function handleBeforeUnload(event)
70 {
71 if (event.returnValue)
72 return;
73 var unsavedSourceCodes = WebInspector.workspace.unsavedSourceCodes();
74 if (!unsavedSourceCodes.length)
75 return;
76
77 event.returnValue = WebInspector.UIString("DevTools have unsaved changes that will be permanently lost.");
78 WebInspector.inspectorView.showPanel("sources");
79 for (var i = 0; i < unsavedSourceCodes.length; ++i)
80 WebInspector.panels.sources.showUISourceCode(unsavedSourceCodes[i]);
81 }
82 window.addEventListener("beforeunload", handleBeforeUnload, true);
83 }
84
85 WebInspector.SourcesView.Events = {
86 EditorClosed: "EditorClosed",
87 EditorSelected: "EditorSelected",
88 }
89
90 WebInspector.SourcesView.prototype = {
91 /**
92 * @param {function(!Array.<!WebInspector.KeyboardShortcut.Descriptor>, func tion(?Event=):boolean)} registerShortcutDelegate
93 */
94 registerShortcuts: function(registerShortcutDelegate)
95 {
96 registerShortcutDelegate(WebInspector.ShortcutsScreen.SourcesPanelShortc uts.JumpToPreviousLocation, this._onJumpToPreviousLocation.bind(this));
97 registerShortcutDelegate(WebInspector.ShortcutsScreen.SourcesPanelShortc uts.JumpToNextLocation, this._onJumpToNextLocation.bind(this));
98 registerShortcutDelegate(WebInspector.ShortcutsScreen.SourcesPanelShortc uts.CloseEditorTab, this._onCloseEditorTab.bind(this));
99 registerShortcutDelegate(WebInspector.ShortcutsScreen.SourcesPanelShortc uts.GoToLine, this._showGoToLineDialog.bind(this));
100 registerShortcutDelegate(WebInspector.ShortcutsScreen.SourcesPanelShortc uts.GoToMember, this._showOutlineDialog.bind(this));
101 registerShortcutDelegate(WebInspector.ShortcutsScreen.SourcesPanelShortc uts.ToggleBreakpoint, this._toggleBreakpoint.bind(this));
102 },
103
104 /**
105 * @return {!Element}
106 */
107 statusBarContainerElement: function()
108 {
109 return this._statusBarContainerElement;
110 },
111
112 /**
113 * @return {!Element}
114 */
115 defaultFocusedElement: function()
116 {
117 return this._editorContainer.view.defaultFocusedElement();
118 },
119
120 /**
121 * @return {!WebInspector.SearchableView}
122 */
123 searchableView: function()
124 {
125 return this._searchableView;
126 },
127
128 /**
129 * @return {!WebInspector.View}
130 */
131 visibleView: function()
132 {
133 return this._editorContainer.visibleView;
134 },
135
136 /**
137 * @return {?WebInspector.SourceFrame}
138 */
139 currentSourceFrame: function()
140 {
141 var view = this.visibleView();
142 if (!(view instanceof WebInspector.SourceFrame))
143 return null;
144 return /** @type {!WebInspector.SourceFrame} */ (view);
145 },
146
147 /**
148 * @return {?WebInspector.UISourceCode}
149 */
150 currentUISourceCode: function()
151 {
152 return this._currentUISourceCode;
153 },
154
155 /**
156 * @param {?Event=} event
157 */
158 _onCloseEditorTab: function(event)
159 {
160 var uiSourceCode = this.currentUISourceCode();
161 if (!uiSourceCode)
162 return false;
163 this._editorContainer.closeFile(uiSourceCode);
164 return true;
165 },
166
167 /**
168 * @param {?Event=} event
169 */
170 _onJumpToPreviousLocation: function(event)
171 {
172 this._historyManager.rollback();
173 return true;
174 },
175
176 /**
177 * @param {?Event=} event
178 */
179 _onJumpToNextLocation: function(event)
180 {
181 this._historyManager.rollover();
182 return true;
183 },
184
185 /**
186 * @param {!WebInspector.Event} event
187 */
188 _uiSourceCodeAdded: function(event)
189 {
190 var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data );
191 this._addUISourceCode(uiSourceCode);
192 },
193
194 /**
195 * @param {!WebInspector.UISourceCode} uiSourceCode
196 */
197 _addUISourceCode: function(uiSourceCode)
198 {
199 if (uiSourceCode.project().isServiceProject())
200 return;
201 this._editorContainer.addUISourceCode(uiSourceCode);
202 // Replace debugger script-based uiSourceCode with a network-based one.
203 var currentUISourceCode = this._currentUISourceCode;
204 if (currentUISourceCode && currentUISourceCode.project().isServiceProjec t() && currentUISourceCode !== uiSourceCode && currentUISourceCode.url === uiSou rceCode.url) {
205 this._showFile(uiSourceCode);
206 this._editorContainer.removeUISourceCode(currentUISourceCode);
207 }
208 },
209
210 _uiSourceCodeRemoved: function(event)
211 {
212 var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data );
213 this._removeUISourceCodes([uiSourceCode]);
214 },
215
216 /**
217 * @param {!Array.<!WebInspector.UISourceCode>} uiSourceCodes
218 */
219 _removeUISourceCodes: function(uiSourceCodes)
220 {
221 for (var i = 0; i < uiSourceCodes.length; ++i) {
222 this._removeSourceFrame(uiSourceCodes[i]);
223 this._historyManager.removeHistoryForSourceCode(uiSourceCodes[i]);
224 }
225 this._editorContainer.removeUISourceCodes(uiSourceCodes);
226 },
227
228 _projectWillReset: function(event)
229 {
230 var project = event.data;
231 var uiSourceCodes = project.uiSourceCodes();
232 this._removeUISourceCodes(uiSourceCodes);
233 if (project.type() === WebInspector.projectTypes.Network)
234 this._editorContainer.reset();
235 },
236
237 _updateScriptViewStatusBarItems: function()
238 {
239 this._scriptViewStatusBarItemsContainer.removeChildren();
240 this._scriptViewStatusBarTextContainer.removeChildren();
241 var sourceFrame = this.currentSourceFrame();
242 if (!sourceFrame)
243 return;
244
245 var statusBarItems = sourceFrame.statusBarItems() || [];
246 for (var i = 0; i < statusBarItems.length; ++i)
247 this._scriptViewStatusBarItemsContainer.appendChild(statusBarItems[i ]);
248 var statusBarText = sourceFrame.statusBarText();
249 if (statusBarText)
250 this._scriptViewStatusBarTextContainer.appendChild(statusBarText);
251 },
252
253 /**
254 * @param {!WebInspector.UISourceCode} uiSourceCode
255 * @param {number=} lineNumber
256 * @param {number=} columnNumber
257 * @param {boolean=} omitFocus
258 * @param {boolean=} omitHighlight
259 */
260 showSourceLocation: function(uiSourceCode, lineNumber, columnNumber, omitFoc us, omitHighlight)
261 {
262 this._historyManager.updateCurrentState();
263 var sourceFrame = this._showFile(uiSourceCode);
264 if (typeof lineNumber === "number")
265 sourceFrame.revealPosition(lineNumber, columnNumber, !omitHighlight) ;
266 this._historyManager.pushNewState();
267 if (!omitFocus)
268 sourceFrame.focus();
269 WebInspector.notifications.dispatchEventToListeners(WebInspector.UserMet rics.UserAction, {
270 action: WebInspector.UserMetrics.UserActionNames.OpenSourceLink,
271 url: uiSourceCode.originURL(),
272 lineNumber: lineNumber
273 });
274 },
275
276 /**
277 * @param {!WebInspector.UISourceCode} uiSourceCode
278 * @return {!WebInspector.SourceFrame}
279 */
280 _showFile: function(uiSourceCode)
281 {
282 var sourceFrame = this._getOrCreateSourceFrame(uiSourceCode);
283 if (this._currentUISourceCode === uiSourceCode)
284 return sourceFrame;
285
286 this._currentUISourceCode = uiSourceCode;
287 this._editorContainer.showFile(uiSourceCode);
288 this._updateScriptViewStatusBarItems();
289 return sourceFrame;
290 },
291
292 /**
293 * @param {!WebInspector.UISourceCode} uiSourceCode
294 * @return {!WebInspector.SourceFrame}
295 */
296 _createSourceFrame: function(uiSourceCode)
297 {
298 var sourceFrame;
299 switch (uiSourceCode.contentType()) {
300 case WebInspector.resourceTypes.Script:
301 sourceFrame = new WebInspector.JavaScriptSourceFrame(this._sourcesPa nel, uiSourceCode);
302 break;
303 case WebInspector.resourceTypes.Document:
304 sourceFrame = new WebInspector.JavaScriptSourceFrame(this._sourcesPa nel, uiSourceCode);
305 break;
306 case WebInspector.resourceTypes.Stylesheet:
307 sourceFrame = new WebInspector.CSSSourceFrame(uiSourceCode);
308 break;
309 default:
310 sourceFrame = new WebInspector.UISourceCodeFrame(uiSourceCode);
311 break;
312 }
313 sourceFrame.setHighlighterType(uiSourceCode.highlighterType());
314 this._sourceFramesByUISourceCode.put(uiSourceCode, sourceFrame);
315 this._historyManager.trackSourceFrameCursorJumps(sourceFrame);
316 return sourceFrame;
317 },
318
319 /**
320 * @param {!WebInspector.UISourceCode} uiSourceCode
321 * @return {!WebInspector.SourceFrame}
322 */
323 _getOrCreateSourceFrame: function(uiSourceCode)
324 {
325 return this._sourceFramesByUISourceCode.get(uiSourceCode) || this._creat eSourceFrame(uiSourceCode);
326 },
327
328 /**
329 * @param {!WebInspector.SourceFrame} sourceFrame
330 * @param {!WebInspector.UISourceCode} uiSourceCode
331 * @return {boolean}
332 */
333 _sourceFrameMatchesUISourceCode: function(sourceFrame, uiSourceCode)
334 {
335 switch (uiSourceCode.contentType()) {
336 case WebInspector.resourceTypes.Script:
337 case WebInspector.resourceTypes.Document:
338 return sourceFrame instanceof WebInspector.JavaScriptSourceFrame;
339 case WebInspector.resourceTypes.Stylesheet:
340 return sourceFrame instanceof WebInspector.CSSSourceFrame;
341 default:
342 return !(sourceFrame instanceof WebInspector.JavaScriptSourceFrame);
343 }
344 },
345
346 /**
347 * @param {!WebInspector.UISourceCode} uiSourceCode
348 */
349 _recreateSourceFrameIfNeeded: function(uiSourceCode)
350 {
351 var oldSourceFrame = this._sourceFramesByUISourceCode.get(uiSourceCode);
352 if (!oldSourceFrame)
353 return;
354 if (this._sourceFrameMatchesUISourceCode(oldSourceFrame, uiSourceCode)) {
355 oldSourceFrame.setHighlighterType(uiSourceCode.highlighterType());
356 } else {
357 this._editorContainer.removeUISourceCode(uiSourceCode);
358 this._removeSourceFrame(uiSourceCode);
359 }
360 },
361
362 /**
363 * @param {!WebInspector.UISourceCode} uiSourceCode
364 * @return {!WebInspector.SourceFrame}
365 */
366 viewForFile: function(uiSourceCode)
367 {
368 return this._getOrCreateSourceFrame(uiSourceCode);
369 },
370
371 /**
372 * @param {!WebInspector.UISourceCode} uiSourceCode
373 */
374 _removeSourceFrame: function(uiSourceCode)
375 {
376 var sourceFrame = this._sourceFramesByUISourceCode.get(uiSourceCode);
377 if (!sourceFrame)
378 return;
379 this._sourceFramesByUISourceCode.remove(uiSourceCode);
380 sourceFrame.dispose();
381 },
382
383 clearCurrentExecutionLine: function()
384 {
385 if (this._executionSourceFrame)
386 this._executionSourceFrame.clearExecutionLine();
387 delete this._executionSourceFrame;
388 },
389
390 setExecutionLine: function(uiLocation)
391 {
392 var sourceFrame = this._getOrCreateSourceFrame(uiLocation.uiSourceCode);
393 sourceFrame.setExecutionLine(uiLocation.lineNumber);
394 this._executionSourceFrame = sourceFrame;
395 },
396
397 _editorClosed: function(event)
398 {
399 var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data );
400 this._historyManager.removeHistoryForSourceCode(uiSourceCode);
401
402 var wasSelected = false;
403 if (this._currentUISourceCode === uiSourceCode) {
404 delete this._currentUISourceCode;
405 wasSelected = true;
406 }
407
408 // SourcesNavigator does not need to update on EditorClosed.
409 this._updateScriptViewStatusBarItems();
410 this._searchableView.resetSearch();
411
412 var data = {};
413 data.uiSourceCode = uiSourceCode;
414 data.wasSelected = wasSelected;
415 this.dispatchEventToListeners(WebInspector.SourcesView.Events.EditorClos ed, data);
416 },
417
418 _editorSelected: function(event)
419 {
420 var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data .currentFile);
421 var shouldUseHistoryManager = uiSourceCode !== this._currentUISourceCode && event.data.userGesture;
422 if (shouldUseHistoryManager)
423 this._historyManager.updateCurrentState();
424 var sourceFrame = this._showFile(uiSourceCode);
425 if (shouldUseHistoryManager)
426 this._historyManager.pushNewState();
427
428 this._searchableView.setReplaceable(!!sourceFrame && sourceFrame.canEdit Source());
429 this._searchableView.resetSearch();
430
431 this.dispatchEventToListeners(WebInspector.SourcesView.Events.EditorSele cted, uiSourceCode);
432 },
433
434 /**
435 * @param {!WebInspector.UISourceCode} uiSourceCode
436 */
437 sourceRenamed: function(uiSourceCode)
438 {
439 this._recreateSourceFrameIfNeeded(uiSourceCode);
440 },
441
442 searchCanceled: function()
443 {
444 if (this._searchView)
445 this._searchView.searchCanceled();
446
447 delete this._searchView;
448 delete this._searchQuery;
449 },
450
451 /**
452 * @param {string} query
453 * @param {boolean} shouldJump
454 */
455 performSearch: function(query, shouldJump)
456 {
457 this._searchableView.updateSearchMatchesCount(0);
458
459 var sourceFrame = this.currentSourceFrame();
460 if (!sourceFrame)
461 return;
462
463 this._searchView = sourceFrame;
464 this._searchQuery = query;
465
466 /**
467 * @param {!WebInspector.View} view
468 * @param {number} searchMatches
469 * @this {WebInspector.SourcesView}
470 */
471 function finishedCallback(view, searchMatches)
472 {
473 if (!searchMatches)
474 return;
475
476 this._searchableView.updateSearchMatchesCount(searchMatches);
477 }
478
479 /**
480 * @param {number} currentMatchIndex
481 * @this {WebInspector.SourcesView}
482 */
483 function currentMatchChanged(currentMatchIndex)
484 {
485 this._searchableView.updateCurrentMatchIndex(currentMatchIndex);
486 }
487
488 /**
489 * @this {WebInspector.SourcesView}
490 */
491 function searchResultsChanged()
492 {
493 this._searchableView.cancelSearch();
494 }
495
496 this._searchView.performSearch(query, shouldJump, finishedCallback.bind( this), currentMatchChanged.bind(this), searchResultsChanged.bind(this));
497 },
498
499 jumpToNextSearchResult: function()
500 {
501 if (!this._searchView)
502 return;
503
504 if (this._searchView !== this.currentSourceFrame()) {
505 this.performSearch(this._searchQuery, true);
506 return;
507 }
508
509 this._searchView.jumpToNextSearchResult();
510 },
511
512 jumpToPreviousSearchResult: function()
513 {
514 if (!this._searchView)
515 return;
516
517 if (this._searchView !== this.currentSourceFrame()) {
518 this.performSearch(this._searchQuery, true);
519 if (this._searchView)
520 this._searchView.jumpToLastSearchResult();
521 return;
522 }
523
524 this._searchView.jumpToPreviousSearchResult();
525 },
526
527 /**
528 * @param {string} text
529 */
530 replaceSelectionWith: function(text)
531 {
532 var sourceFrame = this.currentSourceFrame();
533 if (!sourceFrame) {
534 console.assert(sourceFrame);
535 return;
536 }
537 sourceFrame.replaceSelectionWith(text);
538 },
539
540 /**
541 * @param {string} query
542 * @param {string} text
543 */
544 replaceAllWith: function(query, text)
545 {
546 var sourceFrame = this.currentSourceFrame();
547 if (!sourceFrame) {
548 console.assert(sourceFrame);
549 return;
550 }
551 sourceFrame.replaceAllWith(query, text);
552 },
553
554 /**
555 * @param {?Event=} event
556 * @return {boolean}
557 */
558 _showOutlineDialog: function(event)
559 {
560 var uiSourceCode = this._editorContainer.currentFile();
561 if (!uiSourceCode)
562 return false;
563
564 switch (uiSourceCode.contentType()) {
565 case WebInspector.resourceTypes.Document:
566 case WebInspector.resourceTypes.Script:
567 WebInspector.JavaScriptOutlineDialog.show(this, uiSourceCode, this.s howSourceLocation.bind(this, uiSourceCode));
568 return true;
569 case WebInspector.resourceTypes.Stylesheet:
570 WebInspector.StyleSheetOutlineDialog.show(this, uiSourceCode, this.s howSourceLocation.bind(this, uiSourceCode));
571 return true;
572 }
573 return false;
574 },
575
576 /**
577 * @param {string=} query
578 */
579 showOpenResourceDialog: function(query)
580 {
581 var uiSourceCodes = this._editorContainer.historyUISourceCodes();
582 /** @type {!Map.<!WebInspector.UISourceCode, number>} */
583 var defaultScores = new Map();
584 for (var i = 1; i < uiSourceCodes.length; ++i) // Skip current element
585 defaultScores.put(uiSourceCodes[i], uiSourceCodes.length - i);
586 WebInspector.OpenResourceDialog.show(this, this.element, query, defaultS cores);
587 },
588
589 /**
590 * @param {?Event=} event
591 * @return {boolean}
592 */
593 _showGoToLineDialog: function(event)
594 {
595 this.showOpenResourceDialog(":");
596 return true;
597 },
598
599 /**
600 * @return {boolean}
601 */
602 _toggleBreakpoint: function()
603 {
604 var sourceFrame = this.currentSourceFrame();
605 if (!sourceFrame)
606 return false;
607
608 if (sourceFrame instanceof WebInspector.JavaScriptSourceFrame) {
609 var javaScriptSourceFrame = /** @type {!WebInspector.JavaScriptSourc eFrame} */ (sourceFrame);
610 javaScriptSourceFrame.toggleBreakpointOnCurrentLine();
611 return true;
612 }
613 return false;
614 },
615
616 /**
617 * @param {boolean} active
618 */
619 toggleBreakpointsActiveState: function(active)
620 {
621 this._editorContainer.view.element.classList.toggle("breakpoints-deactiv ated", !active);
622 },
623
624 __proto__: WebInspector.VBox.prototype
625 }
626
627 /**
628 * @interface
629 */
630 WebInspector.SourcesView.EditorAction = function()
631 {
632 }
633
634 WebInspector.SourcesView.EditorAction.prototype = {
635 /**
636 * @param {!WebInspector.SourcesView} sourcesView
637 * @return {!Element}
638 */
639 button: function(sourcesView) { }
640 }
OLDNEW
« no previous file with comments | « Source/devtools/devtools.gypi ('k') | Source/devtools/front_end/SourcesPanel.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698