| OLD | NEW |
| 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 | |
| 7 * @implements {WebInspector.TabbedEditorContainerDelegate} | 5 * @implements {WebInspector.TabbedEditorContainerDelegate} |
| 8 * @implements {WebInspector.Searchable} | 6 * @implements {WebInspector.Searchable} |
| 9 * @implements {WebInspector.Replaceable} | 7 * @implements {WebInspector.Replaceable} |
| 10 * @extends {WebInspector.VBox} | 8 * @unrestricted |
| 11 * @suppressGlobalPropertiesCheck | |
| 12 */ | 9 */ |
| 13 WebInspector.SourcesView = function() | 10 WebInspector.SourcesView = class extends WebInspector.VBox { |
| 14 { | 11 /** |
| 15 WebInspector.VBox.call(this); | 12 * @suppressGlobalPropertiesCheck |
| 16 this.registerRequiredCSS("sources/sourcesView.css"); | 13 */ |
| 17 this.element.id = "sources-panel-sources-view"; | 14 constructor() { |
| 15 super(); |
| 16 this.registerRequiredCSS('sources/sourcesView.css'); |
| 17 this.element.id = 'sources-panel-sources-view'; |
| 18 this.setMinimumAndPreferredSizes(50, 52, 150, 100); | 18 this.setMinimumAndPreferredSizes(50, 52, 150, 100); |
| 19 | 19 |
| 20 var workspace = WebInspector.workspace; | 20 var workspace = WebInspector.workspace; |
| 21 | 21 |
| 22 this._searchableView = new WebInspector.SearchableView(this, "sourcesViewSea
rchConfig"); | 22 this._searchableView = new WebInspector.SearchableView(this, 'sourcesViewSea
rchConfig'); |
| 23 this._searchableView.setMinimalSearchQuerySize(0); | 23 this._searchableView.setMinimalSearchQuerySize(0); |
| 24 this._searchableView.show(this.element); | 24 this._searchableView.show(this.element); |
| 25 | 25 |
| 26 /** @type {!Map.<!WebInspector.UISourceCode, !WebInspector.Widget>} */ | 26 /** @type {!Map.<!WebInspector.UISourceCode, !WebInspector.Widget>} */ |
| 27 this._sourceViewByUISourceCode = new Map(); | 27 this._sourceViewByUISourceCode = new Map(); |
| 28 | 28 |
| 29 var tabbedEditorPlaceholderText = WebInspector.isMac() ? WebInspector.UIStri
ng("Hit Cmd+P to open a file") : WebInspector.UIString("Hit Ctrl+P to open a fil
e"); | 29 var tabbedEditorPlaceholderText = WebInspector.isMac() ? WebInspector.UIStri
ng('Hit Cmd+P to open a file') : |
| 30 this._editorContainer = new WebInspector.TabbedEditorContainer(this, WebInsp
ector.settings.createLocalSetting("previouslyViewedFiles", []), tabbedEditorPlac
eholderText); | 30 WebInspector.UIStri
ng('Hit Ctrl+P to open a file'); |
| 31 this._editorContainer = new WebInspector.TabbedEditorContainer( |
| 32 this, WebInspector.settings.createLocalSetting('previouslyViewedFiles',
[]), tabbedEditorPlaceholderText); |
| 31 this._editorContainer.show(this._searchableView.element); | 33 this._editorContainer.show(this._searchableView.element); |
| 32 this._editorContainer.addEventListener(WebInspector.TabbedEditorContainer.Ev
ents.EditorSelected, this._editorSelected, this); | 34 this._editorContainer.addEventListener( |
| 33 this._editorContainer.addEventListener(WebInspector.TabbedEditorContainer.Ev
ents.EditorClosed, this._editorClosed, this); | 35 WebInspector.TabbedEditorContainer.Events.EditorSelected, this._editorSe
lected, this); |
| 36 this._editorContainer.addEventListener( |
| 37 WebInspector.TabbedEditorContainer.Events.EditorClosed, this._editorClos
ed, this); |
| 34 | 38 |
| 35 this._historyManager = new WebInspector.EditingLocationHistoryManager(this,
this.currentSourceFrame.bind(this)); | 39 this._historyManager = new WebInspector.EditingLocationHistoryManager(this,
this.currentSourceFrame.bind(this)); |
| 36 | 40 |
| 37 this._toolbarContainerElement = this.element.createChild("div", "sources-too
lbar"); | 41 this._toolbarContainerElement = this.element.createChild('div', 'sources-too
lbar'); |
| 38 this._toolbarEditorActions = new WebInspector.Toolbar("", this._toolbarConta
inerElement); | 42 this._toolbarEditorActions = new WebInspector.Toolbar('', this._toolbarConta
inerElement); |
| 39 | 43 |
| 40 self.runtime.allInstances(WebInspector.SourcesView.EditorAction).then(append
ButtonsForExtensions.bind(this)); | 44 self.runtime.allInstances(WebInspector.SourcesView.EditorAction).then(append
ButtonsForExtensions.bind(this)); |
| 41 /** | 45 /** |
| 42 * @param {!Array.<!WebInspector.SourcesView.EditorAction>} actions | 46 * @param {!Array.<!WebInspector.SourcesView.EditorAction>} actions |
| 43 * @this {WebInspector.SourcesView} | 47 * @this {WebInspector.SourcesView} |
| 44 */ | 48 */ |
| 45 function appendButtonsForExtensions(actions) | 49 function appendButtonsForExtensions(actions) { |
| 46 { | 50 for (var i = 0; i < actions.length; ++i) |
| 47 for (var i = 0; i < actions.length; ++i) | 51 this._toolbarEditorActions.appendToolbarItem(actions[i].button(this)); |
| 48 this._toolbarEditorActions.appendToolbarItem(actions[i].button(this)
); | |
| 49 } | 52 } |
| 50 this._scriptViewToolbar = new WebInspector.Toolbar("", this._toolbarContaine
rElement); | 53 this._scriptViewToolbar = new WebInspector.Toolbar('', this._toolbarContaine
rElement); |
| 51 this._toolbarContainerElement.createChild("div", "sources-toolbar-spacer"); | 54 this._toolbarContainerElement.createChild('div', 'sources-toolbar-spacer'); |
| 52 this._bottomToolbar = new WebInspector.Toolbar("", this._toolbarContainerEle
ment); | 55 this._bottomToolbar = new WebInspector.Toolbar('', this._toolbarContainerEle
ment); |
| 53 | 56 |
| 54 WebInspector.startBatchUpdate(); | 57 WebInspector.startBatchUpdate(); |
| 55 workspace.uiSourceCodes().forEach(this._addUISourceCode.bind(this)); | 58 workspace.uiSourceCodes().forEach(this._addUISourceCode.bind(this)); |
| 56 WebInspector.endBatchUpdate(); | 59 WebInspector.endBatchUpdate(); |
| 57 | 60 |
| 58 workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeAdded,
this._uiSourceCodeAdded, this); | 61 workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeAdded,
this._uiSourceCodeAdded, this); |
| 59 workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeRemoved
, this._uiSourceCodeRemoved, this); | 62 workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeRemoved
, this._uiSourceCodeRemoved, this); |
| 60 workspace.addEventListener(WebInspector.Workspace.Events.ProjectRemoved, thi
s._projectRemoved.bind(this), this); | 63 workspace.addEventListener(WebInspector.Workspace.Events.ProjectRemoved, thi
s._projectRemoved.bind(this), this); |
| 61 | 64 |
| 62 /** | 65 /** |
| 63 * @param {!Event} event | 66 * @param {!Event} event |
| 64 */ | 67 */ |
| 65 function handleBeforeUnload(event) | 68 function handleBeforeUnload(event) { |
| 66 { | 69 if (event.returnValue) |
| 67 if (event.returnValue) | 70 return; |
| 68 return; | 71 |
| 69 | 72 var unsavedSourceCodes = []; |
| 70 var unsavedSourceCodes = []; | 73 var projects = WebInspector.workspace.projectsForType(WebInspector.project
Types.FileSystem); |
| 71 var projects = WebInspector.workspace.projectsForType(WebInspector.proje
ctTypes.FileSystem); | 74 for (var i = 0; i < projects.length; ++i) |
| 72 for (var i = 0; i < projects.length; ++i) | 75 unsavedSourceCodes = unsavedSourceCodes.concat(projects[i].uiSourceCodes
().filter(isUnsaved)); |
| 73 unsavedSourceCodes = unsavedSourceCodes.concat(projects[i].uiSourceC
odes().filter(isUnsaved)); | 76 |
| 74 | 77 if (!unsavedSourceCodes.length) |
| 75 if (!unsavedSourceCodes.length) | 78 return; |
| 76 return; | 79 |
| 77 | 80 event.returnValue = WebInspector.UIString('DevTools have unsaved changes t
hat will be permanently lost.'); |
| 78 event.returnValue = WebInspector.UIString("DevTools have unsaved changes
that will be permanently lost."); | 81 WebInspector.viewManager.showView('sources'); |
| 79 WebInspector.viewManager.showView("sources"); | 82 for (var i = 0; i < unsavedSourceCodes.length; ++i) |
| 80 for (var i = 0; i < unsavedSourceCodes.length; ++i) | 83 WebInspector.Revealer.reveal(unsavedSourceCodes[i]); |
| 81 WebInspector.Revealer.reveal(unsavedSourceCodes[i]); | 84 |
| 82 | 85 /** |
| 83 /** | 86 * @param {!WebInspector.UISourceCode} sourceCode |
| 84 * @param {!WebInspector.UISourceCode} sourceCode | 87 * @return {boolean} |
| 85 * @return {boolean} | 88 */ |
| 86 */ | 89 function isUnsaved(sourceCode) { |
| 87 function isUnsaved(sourceCode) | 90 var binding = WebInspector.persistence.binding(sourceCode); |
| 88 { | 91 if (binding) |
| 89 var binding = WebInspector.persistence.binding(sourceCode); | 92 return binding.network.isDirty(); |
| 90 if (binding) | 93 return sourceCode.isDirty(); |
| 91 return binding.network.isDirty(); | 94 } |
| 92 return sourceCode.isDirty(); | |
| 93 } | |
| 94 } | 95 } |
| 95 | 96 |
| 96 if (!window.opener) | 97 if (!window.opener) |
| 97 window.addEventListener("beforeunload", handleBeforeUnload, true); | 98 window.addEventListener('beforeunload', handleBeforeUnload, true); |
| 98 | 99 |
| 99 this._shortcuts = {}; | 100 this._shortcuts = {}; |
| 100 this.element.addEventListener("keydown", this._handleKeyDown.bind(this), fal
se); | 101 this.element.addEventListener('keydown', this._handleKeyDown.bind(this), fal
se); |
| 102 } |
| 103 |
| 104 /** |
| 105 * @param {function(!Array.<!WebInspector.KeyboardShortcut.Descriptor>, functi
on(!Event=):boolean)} registerShortcutDelegate |
| 106 */ |
| 107 registerShortcuts(registerShortcutDelegate) { |
| 108 /** |
| 109 * @this {WebInspector.SourcesView} |
| 110 * @param {!Array.<!WebInspector.KeyboardShortcut.Descriptor>} shortcuts |
| 111 * @param {function(!Event=):boolean} handler |
| 112 */ |
| 113 function registerShortcut(shortcuts, handler) { |
| 114 registerShortcutDelegate(shortcuts, handler); |
| 115 this._registerShortcuts(shortcuts, handler); |
| 116 } |
| 117 |
| 118 registerShortcut.call( |
| 119 this, WebInspector.ShortcutsScreen.SourcesPanelShortcuts.JumpToPreviousL
ocation, |
| 120 this._onJumpToPreviousLocation.bind(this)); |
| 121 registerShortcut.call( |
| 122 this, WebInspector.ShortcutsScreen.SourcesPanelShortcuts.JumpToNextLocat
ion, |
| 123 this._onJumpToNextLocation.bind(this)); |
| 124 registerShortcut.call( |
| 125 this, WebInspector.ShortcutsScreen.SourcesPanelShortcuts.CloseEditorTab,
this._onCloseEditorTab.bind(this)); |
| 126 registerShortcut.call( |
| 127 this, WebInspector.ShortcutsScreen.SourcesPanelShortcuts.GoToLine, this.
_showGoToLineDialog.bind(this)); |
| 128 registerShortcut.call( |
| 129 this, WebInspector.ShortcutsScreen.SourcesPanelShortcuts.GoToMember, thi
s._showOutlineDialog.bind(this)); |
| 130 registerShortcut.call( |
| 131 this, WebInspector.ShortcutsScreen.SourcesPanelShortcuts.ToggleBreakpoin
t, this._toggleBreakpoint.bind(this)); |
| 132 registerShortcut.call(this, WebInspector.ShortcutsScreen.SourcesPanelShortcu
ts.Save, this._save.bind(this)); |
| 133 registerShortcut.call(this, WebInspector.ShortcutsScreen.SourcesPanelShortcu
ts.SaveAll, this._saveAll.bind(this)); |
| 134 } |
| 135 |
| 136 /** |
| 137 * @return {!WebInspector.Toolbar} |
| 138 */ |
| 139 leftToolbar() { |
| 140 return this._editorContainer.leftToolbar(); |
| 141 } |
| 142 |
| 143 /** |
| 144 * @return {!WebInspector.Toolbar} |
| 145 */ |
| 146 rightToolbar() { |
| 147 return this._editorContainer.rightToolbar(); |
| 148 } |
| 149 |
| 150 /** |
| 151 * @return {!WebInspector.Toolbar} |
| 152 */ |
| 153 bottomToolbar() { |
| 154 return this._bottomToolbar; |
| 155 } |
| 156 |
| 157 /** |
| 158 * @param {!Array.<!WebInspector.KeyboardShortcut.Descriptor>} keys |
| 159 * @param {function(!Event=):boolean} handler |
| 160 */ |
| 161 _registerShortcuts(keys, handler) { |
| 162 for (var i = 0; i < keys.length; ++i) |
| 163 this._shortcuts[keys[i].key] = handler; |
| 164 } |
| 165 |
| 166 _handleKeyDown(event) { |
| 167 var shortcutKey = WebInspector.KeyboardShortcut.makeKeyFromEvent(event); |
| 168 var handler = this._shortcuts[shortcutKey]; |
| 169 if (handler && handler()) |
| 170 event.consume(true); |
| 171 } |
| 172 |
| 173 /** |
| 174 * @override |
| 175 */ |
| 176 wasShown() { |
| 177 super.wasShown(); |
| 178 WebInspector.context.setFlavor(WebInspector.SourcesView, this); |
| 179 } |
| 180 |
| 181 /** |
| 182 * @override |
| 183 */ |
| 184 willHide() { |
| 185 WebInspector.context.setFlavor(WebInspector.SourcesView, null); |
| 186 super.willHide(); |
| 187 } |
| 188 |
| 189 /** |
| 190 * @return {!Element} |
| 191 */ |
| 192 toolbarContainerElement() { |
| 193 return this._toolbarContainerElement; |
| 194 } |
| 195 |
| 196 /** |
| 197 * @return {!WebInspector.SearchableView} |
| 198 */ |
| 199 searchableView() { |
| 200 return this._searchableView; |
| 201 } |
| 202 |
| 203 /** |
| 204 * @return {?WebInspector.Widget} |
| 205 */ |
| 206 visibleView() { |
| 207 return this._editorContainer.visibleView; |
| 208 } |
| 209 |
| 210 /** |
| 211 * @return {?WebInspector.UISourceCodeFrame} |
| 212 */ |
| 213 currentSourceFrame() { |
| 214 var view = this.visibleView(); |
| 215 if (!(view instanceof WebInspector.UISourceCodeFrame)) |
| 216 return null; |
| 217 return /** @type {!WebInspector.UISourceCodeFrame} */ (view); |
| 218 } |
| 219 |
| 220 /** |
| 221 * @return {?WebInspector.UISourceCode} |
| 222 */ |
| 223 currentUISourceCode() { |
| 224 return this._editorContainer.currentFile(); |
| 225 } |
| 226 |
| 227 /** |
| 228 * @param {!Event=} event |
| 229 */ |
| 230 _onCloseEditorTab(event) { |
| 231 var uiSourceCode = this._editorContainer.currentFile(); |
| 232 if (!uiSourceCode) |
| 233 return false; |
| 234 this._editorContainer.closeFile(uiSourceCode); |
| 235 return true; |
| 236 } |
| 237 |
| 238 /** |
| 239 * @param {!Event=} event |
| 240 */ |
| 241 _onJumpToPreviousLocation(event) { |
| 242 this._historyManager.rollback(); |
| 243 return true; |
| 244 } |
| 245 |
| 246 /** |
| 247 * @param {!Event=} event |
| 248 */ |
| 249 _onJumpToNextLocation(event) { |
| 250 this._historyManager.rollover(); |
| 251 return true; |
| 252 } |
| 253 |
| 254 /** |
| 255 * @param {!WebInspector.Event} event |
| 256 */ |
| 257 _uiSourceCodeAdded(event) { |
| 258 var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data); |
| 259 this._addUISourceCode(uiSourceCode); |
| 260 } |
| 261 |
| 262 /** |
| 263 * @param {!WebInspector.UISourceCode} uiSourceCode |
| 264 */ |
| 265 _addUISourceCode(uiSourceCode) { |
| 266 if (uiSourceCode.isFromServiceProject()) |
| 267 return; |
| 268 this._editorContainer.addUISourceCode(uiSourceCode); |
| 269 } |
| 270 |
| 271 _uiSourceCodeRemoved(event) { |
| 272 var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data); |
| 273 this._removeUISourceCodes([uiSourceCode]); |
| 274 } |
| 275 |
| 276 /** |
| 277 * @param {!Array.<!WebInspector.UISourceCode>} uiSourceCodes |
| 278 */ |
| 279 _removeUISourceCodes(uiSourceCodes) { |
| 280 this._editorContainer.removeUISourceCodes(uiSourceCodes); |
| 281 for (var i = 0; i < uiSourceCodes.length; ++i) { |
| 282 this._removeSourceFrame(uiSourceCodes[i]); |
| 283 this._historyManager.removeHistoryForSourceCode(uiSourceCodes[i]); |
| 284 } |
| 285 } |
| 286 |
| 287 _projectRemoved(event) { |
| 288 var project = event.data; |
| 289 var uiSourceCodes = project.uiSourceCodes(); |
| 290 this._removeUISourceCodes(uiSourceCodes); |
| 291 } |
| 292 |
| 293 _updateScriptViewToolbarItems() { |
| 294 this._scriptViewToolbar.removeToolbarItems(); |
| 295 var view = this.visibleView(); |
| 296 if (view instanceof WebInspector.SimpleView) { |
| 297 for (var item of (/** @type {?WebInspector.SimpleView} */ (view)).syncTool
barItems()) |
| 298 this._scriptViewToolbar.appendToolbarItem(item); |
| 299 } |
| 300 } |
| 301 |
| 302 /** |
| 303 * @param {!WebInspector.UISourceCode} uiSourceCode |
| 304 * @param {number=} lineNumber 0-based |
| 305 * @param {number=} columnNumber |
| 306 * @param {boolean=} omitFocus |
| 307 * @param {boolean=} omitHighlight |
| 308 */ |
| 309 showSourceLocation(uiSourceCode, lineNumber, columnNumber, omitFocus, omitHigh
light) { |
| 310 this._historyManager.updateCurrentState(); |
| 311 this._editorContainer.showFile(uiSourceCode); |
| 312 var currentSourceFrame = this.currentSourceFrame(); |
| 313 if (currentSourceFrame && typeof lineNumber === 'number') |
| 314 currentSourceFrame.revealPosition(lineNumber, columnNumber, !omitHighlight
); |
| 315 this._historyManager.pushNewState(); |
| 316 if (!omitFocus) |
| 317 this.visibleView().focus(); |
| 318 } |
| 319 |
| 320 /** |
| 321 * @param {!WebInspector.UISourceCode} uiSourceCode |
| 322 * @return {!WebInspector.Widget} |
| 323 */ |
| 324 _createSourceView(uiSourceCode) { |
| 325 var sourceFrame; |
| 326 var sourceView; |
| 327 var contentType = uiSourceCode.contentType(); |
| 328 |
| 329 if (contentType.hasScripts()) |
| 330 sourceFrame = new WebInspector.JavaScriptSourceFrame(uiSourceCode); |
| 331 else if (contentType.isStyleSheet()) |
| 332 sourceFrame = new WebInspector.CSSSourceFrame(uiSourceCode); |
| 333 else if (contentType === WebInspector.resourceTypes.Image) |
| 334 sourceView = |
| 335 new WebInspector.ImageView(WebInspector.NetworkProject.uiSourceCodeMim
eType(uiSourceCode), uiSourceCode); |
| 336 else if (contentType === WebInspector.resourceTypes.Font) |
| 337 sourceView = |
| 338 new WebInspector.FontView(WebInspector.NetworkProject.uiSourceCodeMime
Type(uiSourceCode), uiSourceCode); |
| 339 else |
| 340 sourceFrame = new WebInspector.UISourceCodeFrame(uiSourceCode); |
| 341 |
| 342 if (sourceFrame) { |
| 343 sourceFrame.setHighlighterType(WebInspector.NetworkProject.uiSourceCodeMim
eType(uiSourceCode)); |
| 344 this._historyManager.trackSourceFrameCursorJumps(sourceFrame); |
| 345 } |
| 346 var widget = /** @type {!WebInspector.Widget} */ (sourceFrame || sourceView)
; |
| 347 this._sourceViewByUISourceCode.set(uiSourceCode, widget); |
| 348 uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.TitleChanged,
this._uiSourceCodeTitleChanged, this); |
| 349 return widget; |
| 350 } |
| 351 |
| 352 /** |
| 353 * @param {!WebInspector.UISourceCode} uiSourceCode |
| 354 * @return {!WebInspector.Widget} |
| 355 */ |
| 356 _getOrCreateSourceView(uiSourceCode) { |
| 357 return this._sourceViewByUISourceCode.get(uiSourceCode) || this._createSourc
eView(uiSourceCode); |
| 358 } |
| 359 |
| 360 /** |
| 361 * @param {!WebInspector.UISourceCodeFrame} sourceFrame |
| 362 * @param {!WebInspector.UISourceCode} uiSourceCode |
| 363 * @return {boolean} |
| 364 */ |
| 365 _sourceFrameMatchesUISourceCode(sourceFrame, uiSourceCode) { |
| 366 if (uiSourceCode.contentType().hasScripts()) |
| 367 return sourceFrame instanceof WebInspector.JavaScriptSourceFrame; |
| 368 if (uiSourceCode.contentType().isStyleSheet()) |
| 369 return sourceFrame instanceof WebInspector.CSSSourceFrame; |
| 370 return !(sourceFrame instanceof WebInspector.JavaScriptSourceFrame); |
| 371 } |
| 372 |
| 373 /** |
| 374 * @param {!WebInspector.UISourceCode} uiSourceCode |
| 375 */ |
| 376 _recreateSourceFrameIfNeeded(uiSourceCode) { |
| 377 var oldSourceView = this._sourceViewByUISourceCode.get(uiSourceCode); |
| 378 if (!oldSourceView || !(oldSourceView instanceof WebInspector.UISourceCodeFr
ame)) |
| 379 return; |
| 380 var oldSourceFrame = /** @type {!WebInspector.UISourceCodeFrame} */ (oldSour
ceView); |
| 381 if (this._sourceFrameMatchesUISourceCode(oldSourceFrame, uiSourceCode)) { |
| 382 oldSourceFrame.setHighlighterType(WebInspector.NetworkProject.uiSourceCode
MimeType(uiSourceCode)); |
| 383 } else { |
| 384 this._editorContainer.removeUISourceCode(uiSourceCode); |
| 385 this._removeSourceFrame(uiSourceCode); |
| 386 } |
| 387 } |
| 388 |
| 389 /** |
| 390 * @override |
| 391 * @param {!WebInspector.UISourceCode} uiSourceCode |
| 392 * @return {!WebInspector.Widget} |
| 393 */ |
| 394 viewForFile(uiSourceCode) { |
| 395 return this._getOrCreateSourceView(uiSourceCode); |
| 396 } |
| 397 |
| 398 /** |
| 399 * @param {!WebInspector.UISourceCode} uiSourceCode |
| 400 */ |
| 401 _removeSourceFrame(uiSourceCode) { |
| 402 var sourceView = this._sourceViewByUISourceCode.get(uiSourceCode); |
| 403 this._sourceViewByUISourceCode.remove(uiSourceCode); |
| 404 uiSourceCode.removeEventListener( |
| 405 WebInspector.UISourceCode.Events.TitleChanged, this._uiSourceCodeTitleCh
anged, this); |
| 406 if (sourceView && sourceView instanceof WebInspector.UISourceCodeFrame) |
| 407 /** @type {!WebInspector.UISourceCodeFrame} */ (sourceView).dispose(); |
| 408 } |
| 409 |
| 410 clearCurrentExecutionLine() { |
| 411 if (this._executionSourceFrame) |
| 412 this._executionSourceFrame.clearExecutionLine(); |
| 413 delete this._executionSourceFrame; |
| 414 } |
| 415 |
| 416 /** |
| 417 * @param {!WebInspector.UILocation} uiLocation |
| 418 */ |
| 419 setExecutionLocation(uiLocation) { |
| 420 var sourceView = this._getOrCreateSourceView(uiLocation.uiSourceCode); |
| 421 if (sourceView instanceof WebInspector.UISourceCodeFrame) { |
| 422 var sourceFrame = /** @type {!WebInspector.UISourceCodeFrame} */ (sourceVi
ew); |
| 423 sourceFrame.setExecutionLocation(uiLocation); |
| 424 this._executionSourceFrame = sourceFrame; |
| 425 } |
| 426 } |
| 427 |
| 428 /** |
| 429 * @param {!WebInspector.Event} event |
| 430 */ |
| 431 _editorClosed(event) { |
| 432 var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data); |
| 433 this._historyManager.removeHistoryForSourceCode(uiSourceCode); |
| 434 |
| 435 var wasSelected = false; |
| 436 if (!this._editorContainer.currentFile()) |
| 437 wasSelected = true; |
| 438 |
| 439 // SourcesNavigator does not need to update on EditorClosed. |
| 440 this._updateScriptViewToolbarItems(); |
| 441 this._searchableView.resetSearch(); |
| 442 |
| 443 var data = {}; |
| 444 data.uiSourceCode = uiSourceCode; |
| 445 data.wasSelected = wasSelected; |
| 446 this.dispatchEventToListeners(WebInspector.SourcesView.Events.EditorClosed,
data); |
| 447 } |
| 448 |
| 449 /** |
| 450 * @param {!WebInspector.Event} event |
| 451 */ |
| 452 _editorSelected(event) { |
| 453 var previousSourceFrame = |
| 454 event.data.previousView instanceof WebInspector.UISourceCodeFrame ? even
t.data.previousView : null; |
| 455 if (previousSourceFrame) |
| 456 previousSourceFrame.setSearchableView(null); |
| 457 var currentSourceFrame = |
| 458 event.data.currentView instanceof WebInspector.UISourceCodeFrame ? event
.data.currentView : null; |
| 459 if (currentSourceFrame) |
| 460 currentSourceFrame.setSearchableView(this._searchableView); |
| 461 |
| 462 this._searchableView.setReplaceable(!!currentSourceFrame && currentSourceFra
me.canEditSource()); |
| 463 this._searchableView.refreshSearch(); |
| 464 this._updateScriptViewToolbarItems(); |
| 465 |
| 466 this.dispatchEventToListeners(WebInspector.SourcesView.Events.EditorSelected
, this._editorContainer.currentFile()); |
| 467 } |
| 468 |
| 469 /** |
| 470 * @param {!WebInspector.Event} event |
| 471 */ |
| 472 _uiSourceCodeTitleChanged(event) { |
| 473 this._recreateSourceFrameIfNeeded(/** @type {!WebInspector.UISourceCode} */
(event.target)); |
| 474 } |
| 475 |
| 476 /** |
| 477 * @override |
| 478 */ |
| 479 searchCanceled() { |
| 480 if (this._searchView) |
| 481 this._searchView.searchCanceled(); |
| 482 |
| 483 delete this._searchView; |
| 484 delete this._searchConfig; |
| 485 } |
| 486 |
| 487 /** |
| 488 * @override |
| 489 * @param {!WebInspector.SearchableView.SearchConfig} searchConfig |
| 490 * @param {boolean} shouldJump |
| 491 * @param {boolean=} jumpBackwards |
| 492 */ |
| 493 performSearch(searchConfig, shouldJump, jumpBackwards) { |
| 494 var sourceFrame = this.currentSourceFrame(); |
| 495 if (!sourceFrame) |
| 496 return; |
| 497 |
| 498 this._searchView = sourceFrame; |
| 499 this._searchConfig = searchConfig; |
| 500 |
| 501 this._searchView.performSearch(this._searchConfig, shouldJump, jumpBackwards
); |
| 502 } |
| 503 |
| 504 /** |
| 505 * @override |
| 506 */ |
| 507 jumpToNextSearchResult() { |
| 508 if (!this._searchView) |
| 509 return; |
| 510 |
| 511 if (this._searchView !== this.currentSourceFrame()) { |
| 512 this.performSearch(this._searchConfig, true); |
| 513 return; |
| 514 } |
| 515 |
| 516 this._searchView.jumpToNextSearchResult(); |
| 517 } |
| 518 |
| 519 /** |
| 520 * @override |
| 521 */ |
| 522 jumpToPreviousSearchResult() { |
| 523 if (!this._searchView) |
| 524 return; |
| 525 |
| 526 if (this._searchView !== this.currentSourceFrame()) { |
| 527 this.performSearch(this._searchConfig, true); |
| 528 if (this._searchView) |
| 529 this._searchView.jumpToLastSearchResult(); |
| 530 return; |
| 531 } |
| 532 |
| 533 this._searchView.jumpToPreviousSearchResult(); |
| 534 } |
| 535 |
| 536 /** |
| 537 * @override |
| 538 * @return {boolean} |
| 539 */ |
| 540 supportsCaseSensitiveSearch() { |
| 541 return true; |
| 542 } |
| 543 |
| 544 /** |
| 545 * @override |
| 546 * @return {boolean} |
| 547 */ |
| 548 supportsRegexSearch() { |
| 549 return true; |
| 550 } |
| 551 |
| 552 /** |
| 553 * @override |
| 554 * @param {!WebInspector.SearchableView.SearchConfig} searchConfig |
| 555 * @param {string} replacement |
| 556 */ |
| 557 replaceSelectionWith(searchConfig, replacement) { |
| 558 var sourceFrame = this.currentSourceFrame(); |
| 559 if (!sourceFrame) { |
| 560 console.assert(sourceFrame); |
| 561 return; |
| 562 } |
| 563 sourceFrame.replaceSelectionWith(searchConfig, replacement); |
| 564 } |
| 565 |
| 566 /** |
| 567 * @override |
| 568 * @param {!WebInspector.SearchableView.SearchConfig} searchConfig |
| 569 * @param {string} replacement |
| 570 */ |
| 571 replaceAllWith(searchConfig, replacement) { |
| 572 var sourceFrame = this.currentSourceFrame(); |
| 573 if (!sourceFrame) { |
| 574 console.assert(sourceFrame); |
| 575 return; |
| 576 } |
| 577 sourceFrame.replaceAllWith(searchConfig, replacement); |
| 578 } |
| 579 |
| 580 /** |
| 581 * @param {!Event=} event |
| 582 * @return {boolean} |
| 583 */ |
| 584 _showOutlineDialog(event) { |
| 585 var uiSourceCode = this._editorContainer.currentFile(); |
| 586 if (!uiSourceCode) |
| 587 return false; |
| 588 |
| 589 if (uiSourceCode.contentType().hasScripts()) { |
| 590 WebInspector.JavaScriptOutlineDialog.show(uiSourceCode, this.showSourceLoc
ation.bind(this, uiSourceCode)); |
| 591 return true; |
| 592 } |
| 593 |
| 594 if (uiSourceCode.contentType().isStyleSheet()) { |
| 595 WebInspector.StyleSheetOutlineDialog.show(uiSourceCode, this.showSourceLoc
ation.bind(this, uiSourceCode)); |
| 596 return true; |
| 597 } |
| 598 |
| 599 // We don't want default browser shortcut to be executed, so pretend to hand
le this event. |
| 600 return true; |
| 601 } |
| 602 |
| 603 /** |
| 604 * @param {string=} query |
| 605 */ |
| 606 showOpenResourceDialog(query) { |
| 607 var uiSourceCodes = this._editorContainer.historyUISourceCodes(); |
| 608 /** @type {!Map.<!WebInspector.UISourceCode, number>} */ |
| 609 var defaultScores = new Map(); |
| 610 for (var i = 1; i < uiSourceCodes.length; ++i) // Skip current element |
| 611 defaultScores.set(uiSourceCodes[i], uiSourceCodes.length - i); |
| 612 if (!this._openResourceDialogHistory) |
| 613 this._openResourceDialogHistory = []; |
| 614 WebInspector.OpenResourceDialog.show(this, query || '', defaultScores, this.
_openResourceDialogHistory); |
| 615 } |
| 616 |
| 617 /** |
| 618 * @param {!Event=} event |
| 619 * @return {boolean} |
| 620 */ |
| 621 _showGoToLineDialog(event) { |
| 622 if (this._editorContainer.currentFile()) |
| 623 this.showOpenResourceDialog(':'); |
| 624 return true; |
| 625 } |
| 626 |
| 627 /** |
| 628 * @return {boolean} |
| 629 */ |
| 630 _save() { |
| 631 this._saveSourceFrame(this.currentSourceFrame()); |
| 632 return true; |
| 633 } |
| 634 |
| 635 /** |
| 636 * @return {boolean} |
| 637 */ |
| 638 _saveAll() { |
| 639 var sourceFrames = this._editorContainer.fileViews(); |
| 640 sourceFrames.forEach(this._saveSourceFrame.bind(this)); |
| 641 return true; |
| 642 } |
| 643 |
| 644 /** |
| 645 * @param {?WebInspector.Widget} sourceFrame |
| 646 */ |
| 647 _saveSourceFrame(sourceFrame) { |
| 648 if (!(sourceFrame instanceof WebInspector.UISourceCodeFrame)) |
| 649 return; |
| 650 var uiSourceCodeFrame = /** @type {!WebInspector.UISourceCodeFrame} */ (sour
ceFrame); |
| 651 uiSourceCodeFrame.commitEditing(); |
| 652 } |
| 653 |
| 654 /** |
| 655 * @return {boolean} |
| 656 */ |
| 657 _toggleBreakpoint() { |
| 658 var sourceFrame = this.currentSourceFrame(); |
| 659 if (!sourceFrame) |
| 660 return false; |
| 661 |
| 662 if (sourceFrame instanceof WebInspector.JavaScriptSourceFrame) { |
| 663 var javaScriptSourceFrame = /** @type {!WebInspector.JavaScriptSourceFrame
} */ (sourceFrame); |
| 664 javaScriptSourceFrame.toggleBreakpointOnCurrentLine(); |
| 665 return true; |
| 666 } |
| 667 return false; |
| 668 } |
| 669 |
| 670 /** |
| 671 * @param {boolean} active |
| 672 */ |
| 673 toggleBreakpointsActiveState(active) { |
| 674 this._editorContainer.view.element.classList.toggle('breakpoints-deactivated
', !active); |
| 675 } |
| 101 }; | 676 }; |
| 102 | 677 |
| 103 /** @enum {symbol} */ | 678 /** @enum {symbol} */ |
| 104 WebInspector.SourcesView.Events = { | 679 WebInspector.SourcesView.Events = { |
| 105 EditorClosed: Symbol("EditorClosed"), | 680 EditorClosed: Symbol('EditorClosed'), |
| 106 EditorSelected: Symbol("EditorSelected"), | 681 EditorSelected: Symbol('EditorSelected'), |
| 107 }; | |
| 108 | |
| 109 WebInspector.SourcesView.prototype = { | |
| 110 /** | |
| 111 * @param {function(!Array.<!WebInspector.KeyboardShortcut.Descriptor>, func
tion(!Event=):boolean)} registerShortcutDelegate | |
| 112 */ | |
| 113 registerShortcuts: function(registerShortcutDelegate) | |
| 114 { | |
| 115 /** | |
| 116 * @this {WebInspector.SourcesView} | |
| 117 * @param {!Array.<!WebInspector.KeyboardShortcut.Descriptor>} shortcuts | |
| 118 * @param {function(!Event=):boolean} handler | |
| 119 */ | |
| 120 function registerShortcut(shortcuts, handler) | |
| 121 { | |
| 122 registerShortcutDelegate(shortcuts, handler); | |
| 123 this._registerShortcuts(shortcuts, handler); | |
| 124 } | |
| 125 | |
| 126 registerShortcut.call(this, WebInspector.ShortcutsScreen.SourcesPanelSho
rtcuts.JumpToPreviousLocation, this._onJumpToPreviousLocation.bind(this)); | |
| 127 registerShortcut.call(this, WebInspector.ShortcutsScreen.SourcesPanelSho
rtcuts.JumpToNextLocation, this._onJumpToNextLocation.bind(this)); | |
| 128 registerShortcut.call(this, WebInspector.ShortcutsScreen.SourcesPanelSho
rtcuts.CloseEditorTab, this._onCloseEditorTab.bind(this)); | |
| 129 registerShortcut.call(this, WebInspector.ShortcutsScreen.SourcesPanelSho
rtcuts.GoToLine, this._showGoToLineDialog.bind(this)); | |
| 130 registerShortcut.call(this, WebInspector.ShortcutsScreen.SourcesPanelSho
rtcuts.GoToMember, this._showOutlineDialog.bind(this)); | |
| 131 registerShortcut.call(this, WebInspector.ShortcutsScreen.SourcesPanelSho
rtcuts.ToggleBreakpoint, this._toggleBreakpoint.bind(this)); | |
| 132 registerShortcut.call(this, WebInspector.ShortcutsScreen.SourcesPanelSho
rtcuts.Save, this._save.bind(this)); | |
| 133 registerShortcut.call(this, WebInspector.ShortcutsScreen.SourcesPanelSho
rtcuts.SaveAll, this._saveAll.bind(this)); | |
| 134 }, | |
| 135 | |
| 136 /** | |
| 137 * @return {!WebInspector.Toolbar} | |
| 138 */ | |
| 139 leftToolbar: function() | |
| 140 { | |
| 141 return this._editorContainer.leftToolbar(); | |
| 142 }, | |
| 143 | |
| 144 /** | |
| 145 * @return {!WebInspector.Toolbar} | |
| 146 */ | |
| 147 rightToolbar: function() | |
| 148 { | |
| 149 return this._editorContainer.rightToolbar(); | |
| 150 }, | |
| 151 | |
| 152 /** | |
| 153 * @return {!WebInspector.Toolbar} | |
| 154 */ | |
| 155 bottomToolbar: function() | |
| 156 { | |
| 157 return this._bottomToolbar; | |
| 158 }, | |
| 159 | |
| 160 /** | |
| 161 * @param {!Array.<!WebInspector.KeyboardShortcut.Descriptor>} keys | |
| 162 * @param {function(!Event=):boolean} handler | |
| 163 */ | |
| 164 _registerShortcuts: function(keys, handler) | |
| 165 { | |
| 166 for (var i = 0; i < keys.length; ++i) | |
| 167 this._shortcuts[keys[i].key] = handler; | |
| 168 }, | |
| 169 | |
| 170 _handleKeyDown: function(event) | |
| 171 { | |
| 172 var shortcutKey = WebInspector.KeyboardShortcut.makeKeyFromEvent(event); | |
| 173 var handler = this._shortcuts[shortcutKey]; | |
| 174 if (handler && handler()) | |
| 175 event.consume(true); | |
| 176 }, | |
| 177 | |
| 178 wasShown: function() | |
| 179 { | |
| 180 WebInspector.VBox.prototype.wasShown.call(this); | |
| 181 WebInspector.context.setFlavor(WebInspector.SourcesView, this); | |
| 182 }, | |
| 183 | |
| 184 willHide: function() | |
| 185 { | |
| 186 WebInspector.context.setFlavor(WebInspector.SourcesView, null); | |
| 187 WebInspector.VBox.prototype.willHide.call(this); | |
| 188 }, | |
| 189 | |
| 190 /** | |
| 191 * @return {!Element} | |
| 192 */ | |
| 193 toolbarContainerElement: function() | |
| 194 { | |
| 195 return this._toolbarContainerElement; | |
| 196 }, | |
| 197 | |
| 198 /** | |
| 199 * @return {!WebInspector.SearchableView} | |
| 200 */ | |
| 201 searchableView: function() | |
| 202 { | |
| 203 return this._searchableView; | |
| 204 }, | |
| 205 | |
| 206 /** | |
| 207 * @return {!WebInspector.Widget} | |
| 208 */ | |
| 209 visibleView: function() | |
| 210 { | |
| 211 return this._editorContainer.visibleView; | |
| 212 }, | |
| 213 | |
| 214 /** | |
| 215 * @return {?WebInspector.UISourceCodeFrame} | |
| 216 */ | |
| 217 currentSourceFrame: function() | |
| 218 { | |
| 219 var view = this.visibleView(); | |
| 220 if (!(view instanceof WebInspector.UISourceCodeFrame)) | |
| 221 return null; | |
| 222 return /** @type {!WebInspector.UISourceCodeFrame} */ (view); | |
| 223 }, | |
| 224 | |
| 225 /** | |
| 226 * @return {?WebInspector.UISourceCode} | |
| 227 */ | |
| 228 currentUISourceCode: function() | |
| 229 { | |
| 230 return this._editorContainer.currentFile(); | |
| 231 }, | |
| 232 | |
| 233 /** | |
| 234 * @param {!Event=} event | |
| 235 */ | |
| 236 _onCloseEditorTab: function(event) | |
| 237 { | |
| 238 var uiSourceCode = this._editorContainer.currentFile(); | |
| 239 if (!uiSourceCode) | |
| 240 return false; | |
| 241 this._editorContainer.closeFile(uiSourceCode); | |
| 242 return true; | |
| 243 }, | |
| 244 | |
| 245 /** | |
| 246 * @param {!Event=} event | |
| 247 */ | |
| 248 _onJumpToPreviousLocation: function(event) | |
| 249 { | |
| 250 this._historyManager.rollback(); | |
| 251 return true; | |
| 252 }, | |
| 253 | |
| 254 /** | |
| 255 * @param {!Event=} event | |
| 256 */ | |
| 257 _onJumpToNextLocation: function(event) | |
| 258 { | |
| 259 this._historyManager.rollover(); | |
| 260 return true; | |
| 261 }, | |
| 262 | |
| 263 /** | |
| 264 * @param {!WebInspector.Event} event | |
| 265 */ | |
| 266 _uiSourceCodeAdded: function(event) | |
| 267 { | |
| 268 var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data
); | |
| 269 this._addUISourceCode(uiSourceCode); | |
| 270 }, | |
| 271 | |
| 272 /** | |
| 273 * @param {!WebInspector.UISourceCode} uiSourceCode | |
| 274 */ | |
| 275 _addUISourceCode: function(uiSourceCode) | |
| 276 { | |
| 277 if (uiSourceCode.isFromServiceProject()) | |
| 278 return; | |
| 279 this._editorContainer.addUISourceCode(uiSourceCode); | |
| 280 }, | |
| 281 | |
| 282 _uiSourceCodeRemoved: function(event) | |
| 283 { | |
| 284 var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data
); | |
| 285 this._removeUISourceCodes([uiSourceCode]); | |
| 286 }, | |
| 287 | |
| 288 /** | |
| 289 * @param {!Array.<!WebInspector.UISourceCode>} uiSourceCodes | |
| 290 */ | |
| 291 _removeUISourceCodes: function(uiSourceCodes) | |
| 292 { | |
| 293 this._editorContainer.removeUISourceCodes(uiSourceCodes); | |
| 294 for (var i = 0; i < uiSourceCodes.length; ++i) { | |
| 295 this._removeSourceFrame(uiSourceCodes[i]); | |
| 296 this._historyManager.removeHistoryForSourceCode(uiSourceCodes[i]); | |
| 297 } | |
| 298 }, | |
| 299 | |
| 300 _projectRemoved: function(event) | |
| 301 { | |
| 302 var project = event.data; | |
| 303 var uiSourceCodes = project.uiSourceCodes(); | |
| 304 this._removeUISourceCodes(uiSourceCodes); | |
| 305 }, | |
| 306 | |
| 307 _updateScriptViewToolbarItems: function() | |
| 308 { | |
| 309 this._scriptViewToolbar.removeToolbarItems(); | |
| 310 var view = this.visibleView(); | |
| 311 if (view instanceof WebInspector.SimpleView) { | |
| 312 for (var item of (/** @type {?WebInspector.SimpleView} */(view)).syn
cToolbarItems()) | |
| 313 this._scriptViewToolbar.appendToolbarItem(item); | |
| 314 } | |
| 315 }, | |
| 316 | |
| 317 /** | |
| 318 * @param {!WebInspector.UISourceCode} uiSourceCode | |
| 319 * @param {number=} lineNumber 0-based | |
| 320 * @param {number=} columnNumber | |
| 321 * @param {boolean=} omitFocus | |
| 322 * @param {boolean=} omitHighlight | |
| 323 */ | |
| 324 showSourceLocation: function(uiSourceCode, lineNumber, columnNumber, omitFoc
us, omitHighlight) | |
| 325 { | |
| 326 this._historyManager.updateCurrentState(); | |
| 327 this._editorContainer.showFile(uiSourceCode); | |
| 328 var currentSourceFrame = this.currentSourceFrame(); | |
| 329 if (currentSourceFrame && typeof lineNumber === "number") | |
| 330 currentSourceFrame.revealPosition(lineNumber, columnNumber, !omitHig
hlight); | |
| 331 this._historyManager.pushNewState(); | |
| 332 if (!omitFocus) | |
| 333 this.visibleView().focus(); | |
| 334 }, | |
| 335 | |
| 336 /** | |
| 337 * @param {!WebInspector.UISourceCode} uiSourceCode | |
| 338 * @return {!WebInspector.Widget} | |
| 339 */ | |
| 340 _createSourceView: function(uiSourceCode) | |
| 341 { | |
| 342 var sourceFrame; | |
| 343 var sourceView; | |
| 344 var contentType = uiSourceCode.contentType(); | |
| 345 | |
| 346 if (contentType.hasScripts()) | |
| 347 sourceFrame = new WebInspector.JavaScriptSourceFrame(uiSourceCode); | |
| 348 else if (contentType.isStyleSheet()) | |
| 349 sourceFrame = new WebInspector.CSSSourceFrame(uiSourceCode); | |
| 350 else if (contentType === WebInspector.resourceTypes.Image) | |
| 351 sourceView = new WebInspector.ImageView(WebInspector.NetworkProject.
uiSourceCodeMimeType(uiSourceCode), uiSourceCode); | |
| 352 else if (contentType === WebInspector.resourceTypes.Font) | |
| 353 sourceView = new WebInspector.FontView(WebInspector.NetworkProject.u
iSourceCodeMimeType(uiSourceCode), uiSourceCode); | |
| 354 else | |
| 355 sourceFrame = new WebInspector.UISourceCodeFrame(uiSourceCode); | |
| 356 | |
| 357 if (sourceFrame) { | |
| 358 sourceFrame.setHighlighterType(WebInspector.NetworkProject.uiSourceC
odeMimeType(uiSourceCode)); | |
| 359 this._historyManager.trackSourceFrameCursorJumps(sourceFrame); | |
| 360 } | |
| 361 var widget = /** @type {!WebInspector.Widget} */(sourceFrame || sourceVi
ew); | |
| 362 this._sourceViewByUISourceCode.set(uiSourceCode, widget); | |
| 363 uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.TitleChan
ged, this._uiSourceCodeTitleChanged, this); | |
| 364 return widget; | |
| 365 }, | |
| 366 | |
| 367 /** | |
| 368 * @param {!WebInspector.UISourceCode} uiSourceCode | |
| 369 * @return {!WebInspector.Widget} | |
| 370 */ | |
| 371 _getOrCreateSourceView: function(uiSourceCode) | |
| 372 { | |
| 373 return this._sourceViewByUISourceCode.get(uiSourceCode) || this._createS
ourceView(uiSourceCode); | |
| 374 }, | |
| 375 | |
| 376 /** | |
| 377 * @param {!WebInspector.UISourceCodeFrame} sourceFrame | |
| 378 * @param {!WebInspector.UISourceCode} uiSourceCode | |
| 379 * @return {boolean} | |
| 380 */ | |
| 381 _sourceFrameMatchesUISourceCode: function(sourceFrame, uiSourceCode) | |
| 382 { | |
| 383 if (uiSourceCode.contentType().hasScripts()) | |
| 384 return sourceFrame instanceof WebInspector.JavaScriptSourceFrame; | |
| 385 if (uiSourceCode.contentType().isStyleSheet()) | |
| 386 return sourceFrame instanceof WebInspector.CSSSourceFrame; | |
| 387 return !(sourceFrame instanceof WebInspector.JavaScriptSourceFrame); | |
| 388 }, | |
| 389 | |
| 390 /** | |
| 391 * @param {!WebInspector.UISourceCode} uiSourceCode | |
| 392 */ | |
| 393 _recreateSourceFrameIfNeeded: function(uiSourceCode) | |
| 394 { | |
| 395 var oldSourceView = this._sourceViewByUISourceCode.get(uiSourceCode); | |
| 396 if (!oldSourceView || !(oldSourceView instanceof WebInspector.UISourceCo
deFrame)) | |
| 397 return; | |
| 398 var oldSourceFrame = /** @type {!WebInspector.UISourceCodeFrame} */(oldS
ourceView); | |
| 399 if (this._sourceFrameMatchesUISourceCode(oldSourceFrame, uiSourceCode))
{ | |
| 400 oldSourceFrame.setHighlighterType(WebInspector.NetworkProject.uiSour
ceCodeMimeType(uiSourceCode)); | |
| 401 } else { | |
| 402 this._editorContainer.removeUISourceCode(uiSourceCode); | |
| 403 this._removeSourceFrame(uiSourceCode); | |
| 404 } | |
| 405 }, | |
| 406 | |
| 407 /** | |
| 408 * @override | |
| 409 * @param {!WebInspector.UISourceCode} uiSourceCode | |
| 410 * @return {!WebInspector.Widget} | |
| 411 */ | |
| 412 viewForFile: function(uiSourceCode) | |
| 413 { | |
| 414 return this._getOrCreateSourceView(uiSourceCode); | |
| 415 }, | |
| 416 | |
| 417 /** | |
| 418 * @param {!WebInspector.UISourceCode} uiSourceCode | |
| 419 */ | |
| 420 _removeSourceFrame: function(uiSourceCode) | |
| 421 { | |
| 422 var sourceView = this._sourceViewByUISourceCode.get(uiSourceCode); | |
| 423 this._sourceViewByUISourceCode.remove(uiSourceCode); | |
| 424 uiSourceCode.removeEventListener(WebInspector.UISourceCode.Events.TitleC
hanged, this._uiSourceCodeTitleChanged, this); | |
| 425 if (sourceView && sourceView instanceof WebInspector.UISourceCodeFrame) | |
| 426 /** @type {!WebInspector.UISourceCodeFrame} */ (sourceView).dispose(
); | |
| 427 }, | |
| 428 | |
| 429 clearCurrentExecutionLine: function() | |
| 430 { | |
| 431 if (this._executionSourceFrame) | |
| 432 this._executionSourceFrame.clearExecutionLine(); | |
| 433 delete this._executionSourceFrame; | |
| 434 }, | |
| 435 | |
| 436 /** | |
| 437 * @param {!WebInspector.UILocation} uiLocation | |
| 438 */ | |
| 439 setExecutionLocation: function(uiLocation) | |
| 440 { | |
| 441 var sourceView = this._getOrCreateSourceView(uiLocation.uiSourceCode); | |
| 442 if (sourceView instanceof WebInspector.UISourceCodeFrame) { | |
| 443 var sourceFrame = /** @type {!WebInspector.UISourceCodeFrame} */(sou
rceView); | |
| 444 sourceFrame.setExecutionLocation(uiLocation); | |
| 445 this._executionSourceFrame = sourceFrame; | |
| 446 } | |
| 447 }, | |
| 448 | |
| 449 /** | |
| 450 * @param {!WebInspector.Event} event | |
| 451 */ | |
| 452 _editorClosed: function(event) | |
| 453 { | |
| 454 var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data
); | |
| 455 this._historyManager.removeHistoryForSourceCode(uiSourceCode); | |
| 456 | |
| 457 var wasSelected = false; | |
| 458 if (!this._editorContainer.currentFile()) | |
| 459 wasSelected = true; | |
| 460 | |
| 461 // SourcesNavigator does not need to update on EditorClosed. | |
| 462 this._updateScriptViewToolbarItems(); | |
| 463 this._searchableView.resetSearch(); | |
| 464 | |
| 465 var data = {}; | |
| 466 data.uiSourceCode = uiSourceCode; | |
| 467 data.wasSelected = wasSelected; | |
| 468 this.dispatchEventToListeners(WebInspector.SourcesView.Events.EditorClos
ed, data); | |
| 469 }, | |
| 470 | |
| 471 /** | |
| 472 * @param {!WebInspector.Event} event | |
| 473 */ | |
| 474 _editorSelected: function(event) | |
| 475 { | |
| 476 var previousSourceFrame = event.data.previousView instanceof WebInspecto
r.UISourceCodeFrame ? event.data.previousView : null; | |
| 477 if (previousSourceFrame) | |
| 478 previousSourceFrame.setSearchableView(null); | |
| 479 var currentSourceFrame = event.data.currentView instanceof WebInspector.
UISourceCodeFrame ? event.data.currentView : null; | |
| 480 if (currentSourceFrame) | |
| 481 currentSourceFrame.setSearchableView(this._searchableView); | |
| 482 | |
| 483 this._searchableView.setReplaceable(!!currentSourceFrame && currentSourc
eFrame.canEditSource()); | |
| 484 this._searchableView.refreshSearch(); | |
| 485 this._updateScriptViewToolbarItems(); | |
| 486 | |
| 487 this.dispatchEventToListeners(WebInspector.SourcesView.Events.EditorSele
cted, this._editorContainer.currentFile()); | |
| 488 }, | |
| 489 | |
| 490 /** | |
| 491 * @param {!WebInspector.Event} event | |
| 492 */ | |
| 493 _uiSourceCodeTitleChanged: function(event) | |
| 494 { | |
| 495 this._recreateSourceFrameIfNeeded(/** @type {!WebInspector.UISourceCode}
*/ (event.target)); | |
| 496 }, | |
| 497 | |
| 498 /** | |
| 499 * @override | |
| 500 */ | |
| 501 searchCanceled: function() | |
| 502 { | |
| 503 if (this._searchView) | |
| 504 this._searchView.searchCanceled(); | |
| 505 | |
| 506 delete this._searchView; | |
| 507 delete this._searchConfig; | |
| 508 }, | |
| 509 | |
| 510 /** | |
| 511 * @override | |
| 512 * @param {!WebInspector.SearchableView.SearchConfig} searchConfig | |
| 513 * @param {boolean} shouldJump | |
| 514 * @param {boolean=} jumpBackwards | |
| 515 */ | |
| 516 performSearch: function(searchConfig, shouldJump, jumpBackwards) | |
| 517 { | |
| 518 var sourceFrame = this.currentSourceFrame(); | |
| 519 if (!sourceFrame) | |
| 520 return; | |
| 521 | |
| 522 this._searchView = sourceFrame; | |
| 523 this._searchConfig = searchConfig; | |
| 524 | |
| 525 this._searchView.performSearch(this._searchConfig, shouldJump, jumpBackw
ards); | |
| 526 }, | |
| 527 | |
| 528 /** | |
| 529 * @override | |
| 530 */ | |
| 531 jumpToNextSearchResult: function() | |
| 532 { | |
| 533 if (!this._searchView) | |
| 534 return; | |
| 535 | |
| 536 if (this._searchView !== this.currentSourceFrame()) { | |
| 537 this.performSearch(this._searchConfig, true); | |
| 538 return; | |
| 539 } | |
| 540 | |
| 541 this._searchView.jumpToNextSearchResult(); | |
| 542 }, | |
| 543 | |
| 544 /** | |
| 545 * @override | |
| 546 */ | |
| 547 jumpToPreviousSearchResult: function() | |
| 548 { | |
| 549 if (!this._searchView) | |
| 550 return; | |
| 551 | |
| 552 if (this._searchView !== this.currentSourceFrame()) { | |
| 553 this.performSearch(this._searchConfig, true); | |
| 554 if (this._searchView) | |
| 555 this._searchView.jumpToLastSearchResult(); | |
| 556 return; | |
| 557 } | |
| 558 | |
| 559 this._searchView.jumpToPreviousSearchResult(); | |
| 560 }, | |
| 561 | |
| 562 /** | |
| 563 * @override | |
| 564 * @return {boolean} | |
| 565 */ | |
| 566 supportsCaseSensitiveSearch: function() | |
| 567 { | |
| 568 return true; | |
| 569 }, | |
| 570 | |
| 571 /** | |
| 572 * @override | |
| 573 * @return {boolean} | |
| 574 */ | |
| 575 supportsRegexSearch: function() | |
| 576 { | |
| 577 return true; | |
| 578 }, | |
| 579 | |
| 580 /** | |
| 581 * @override | |
| 582 * @param {!WebInspector.SearchableView.SearchConfig} searchConfig | |
| 583 * @param {string} replacement | |
| 584 */ | |
| 585 replaceSelectionWith: function(searchConfig, replacement) | |
| 586 { | |
| 587 var sourceFrame = this.currentSourceFrame(); | |
| 588 if (!sourceFrame) { | |
| 589 console.assert(sourceFrame); | |
| 590 return; | |
| 591 } | |
| 592 sourceFrame.replaceSelectionWith(searchConfig, replacement); | |
| 593 }, | |
| 594 | |
| 595 /** | |
| 596 * @override | |
| 597 * @param {!WebInspector.SearchableView.SearchConfig} searchConfig | |
| 598 * @param {string} replacement | |
| 599 */ | |
| 600 replaceAllWith: function(searchConfig, replacement) | |
| 601 { | |
| 602 var sourceFrame = this.currentSourceFrame(); | |
| 603 if (!sourceFrame) { | |
| 604 console.assert(sourceFrame); | |
| 605 return; | |
| 606 } | |
| 607 sourceFrame.replaceAllWith(searchConfig, replacement); | |
| 608 }, | |
| 609 | |
| 610 /** | |
| 611 * @param {!Event=} event | |
| 612 * @return {boolean} | |
| 613 */ | |
| 614 _showOutlineDialog: function(event) | |
| 615 { | |
| 616 var uiSourceCode = this._editorContainer.currentFile(); | |
| 617 if (!uiSourceCode) | |
| 618 return false; | |
| 619 | |
| 620 if (uiSourceCode.contentType().hasScripts()) { | |
| 621 WebInspector.JavaScriptOutlineDialog.show(uiSourceCode, this.showSou
rceLocation.bind(this, uiSourceCode)); | |
| 622 return true; | |
| 623 } | |
| 624 | |
| 625 if (uiSourceCode.contentType().isStyleSheet()) { | |
| 626 WebInspector.StyleSheetOutlineDialog.show(uiSourceCode, this.showSou
rceLocation.bind(this, uiSourceCode)); | |
| 627 return true; | |
| 628 } | |
| 629 | |
| 630 // We don't want default browser shortcut to be executed, so pretend to
handle this event. | |
| 631 return true; | |
| 632 }, | |
| 633 | |
| 634 /** | |
| 635 * @param {string=} query | |
| 636 */ | |
| 637 showOpenResourceDialog: function(query) | |
| 638 { | |
| 639 var uiSourceCodes = this._editorContainer.historyUISourceCodes(); | |
| 640 /** @type {!Map.<!WebInspector.UISourceCode, number>} */ | |
| 641 var defaultScores = new Map(); | |
| 642 for (var i = 1; i < uiSourceCodes.length; ++i) // Skip current element | |
| 643 defaultScores.set(uiSourceCodes[i], uiSourceCodes.length - i); | |
| 644 if (!this._openResourceDialogHistory) | |
| 645 this._openResourceDialogHistory = []; | |
| 646 WebInspector.OpenResourceDialog.show(this, query || "", defaultScores, t
his._openResourceDialogHistory); | |
| 647 }, | |
| 648 | |
| 649 /** | |
| 650 * @param {!Event=} event | |
| 651 * @return {boolean} | |
| 652 */ | |
| 653 _showGoToLineDialog: function(event) | |
| 654 { | |
| 655 if (this._editorContainer.currentFile()) | |
| 656 this.showOpenResourceDialog(":"); | |
| 657 return true; | |
| 658 }, | |
| 659 | |
| 660 /** | |
| 661 * @return {boolean} | |
| 662 */ | |
| 663 _save: function() | |
| 664 { | |
| 665 this._saveSourceFrame(this.currentSourceFrame()); | |
| 666 return true; | |
| 667 }, | |
| 668 | |
| 669 /** | |
| 670 * @return {boolean} | |
| 671 */ | |
| 672 _saveAll: function() | |
| 673 { | |
| 674 var sourceFrames = this._editorContainer.fileViews(); | |
| 675 sourceFrames.forEach(this._saveSourceFrame.bind(this)); | |
| 676 return true; | |
| 677 }, | |
| 678 | |
| 679 /** | |
| 680 * @param {?WebInspector.Widget} sourceFrame | |
| 681 */ | |
| 682 _saveSourceFrame: function(sourceFrame) | |
| 683 { | |
| 684 if (!(sourceFrame instanceof WebInspector.UISourceCodeFrame)) | |
| 685 return; | |
| 686 var uiSourceCodeFrame = /** @type {!WebInspector.UISourceCodeFrame} */ (
sourceFrame); | |
| 687 uiSourceCodeFrame.commitEditing(); | |
| 688 }, | |
| 689 | |
| 690 /** | |
| 691 * @return {boolean} | |
| 692 */ | |
| 693 _toggleBreakpoint: function() | |
| 694 { | |
| 695 var sourceFrame = this.currentSourceFrame(); | |
| 696 if (!sourceFrame) | |
| 697 return false; | |
| 698 | |
| 699 if (sourceFrame instanceof WebInspector.JavaScriptSourceFrame) { | |
| 700 var javaScriptSourceFrame = /** @type {!WebInspector.JavaScriptSourc
eFrame} */ (sourceFrame); | |
| 701 javaScriptSourceFrame.toggleBreakpointOnCurrentLine(); | |
| 702 return true; | |
| 703 } | |
| 704 return false; | |
| 705 }, | |
| 706 | |
| 707 /** | |
| 708 * @param {boolean} active | |
| 709 */ | |
| 710 toggleBreakpointsActiveState: function(active) | |
| 711 { | |
| 712 this._editorContainer.view.element.classList.toggle("breakpoints-deactiv
ated", !active); | |
| 713 }, | |
| 714 | |
| 715 __proto__: WebInspector.VBox.prototype | |
| 716 }; | 682 }; |
| 717 | 683 |
| 718 /** | 684 /** |
| 719 * @interface | 685 * @interface |
| 720 */ | 686 */ |
| 721 WebInspector.SourcesView.EditorAction = function() | 687 WebInspector.SourcesView.EditorAction = function() {}; |
| 722 { | 688 |
| 689 WebInspector.SourcesView.EditorAction.prototype = { |
| 690 /** |
| 691 * @param {!WebInspector.SourcesView} sourcesView |
| 692 * @return {!WebInspector.ToolbarButton} |
| 693 */ |
| 694 button: function(sourcesView) {} |
| 723 }; | 695 }; |
| 724 | 696 |
| 725 WebInspector.SourcesView.EditorAction.prototype = { | |
| 726 /** | |
| 727 * @param {!WebInspector.SourcesView} sourcesView | |
| 728 * @return {!WebInspector.ToolbarButton} | |
| 729 */ | |
| 730 button: function(sourcesView) { } | |
| 731 }; | |
| 732 | |
| 733 /** | 697 /** |
| 734 * @constructor | |
| 735 * @implements {WebInspector.ActionDelegate} | 698 * @implements {WebInspector.ActionDelegate} |
| 699 * @unrestricted |
| 736 */ | 700 */ |
| 737 WebInspector.SourcesView.SwitchFileActionDelegate = function() | 701 WebInspector.SourcesView.SwitchFileActionDelegate = class { |
| 738 { | 702 /** |
| 739 }; | 703 * @param {!WebInspector.UISourceCode} currentUISourceCode |
| 740 | 704 * @return {?WebInspector.UISourceCode} |
| 741 /** | 705 */ |
| 742 * @param {!WebInspector.UISourceCode} currentUISourceCode | 706 static _nextFile(currentUISourceCode) { |
| 743 * @return {?WebInspector.UISourceCode} | |
| 744 */ | |
| 745 WebInspector.SourcesView.SwitchFileActionDelegate._nextFile = function(currentUI
SourceCode) | |
| 746 { | |
| 747 /** | 707 /** |
| 748 * @param {string} name | 708 * @param {string} name |
| 749 * @return {string} | 709 * @return {string} |
| 750 */ | 710 */ |
| 751 function fileNamePrefix(name) | 711 function fileNamePrefix(name) { |
| 752 { | 712 var lastDotIndex = name.lastIndexOf('.'); |
| 753 var lastDotIndex = name.lastIndexOf("."); | 713 var namePrefix = name.substr(0, lastDotIndex !== -1 ? lastDotIndex : name.
length); |
| 754 var namePrefix = name.substr(0, lastDotIndex !== -1 ? lastDotIndex : nam
e.length); | 714 return namePrefix.toLowerCase(); |
| 755 return namePrefix.toLowerCase(); | |
| 756 } | 715 } |
| 757 | 716 |
| 758 var uiSourceCodes = currentUISourceCode.project().uiSourceCodes(); | 717 var uiSourceCodes = currentUISourceCode.project().uiSourceCodes(); |
| 759 var candidates = []; | 718 var candidates = []; |
| 760 var url = currentUISourceCode.parentURL(); | 719 var url = currentUISourceCode.parentURL(); |
| 761 var name = currentUISourceCode.name(); | 720 var name = currentUISourceCode.name(); |
| 762 var namePrefix = fileNamePrefix(name); | 721 var namePrefix = fileNamePrefix(name); |
| 763 for (var i = 0; i < uiSourceCodes.length; ++i) { | 722 for (var i = 0; i < uiSourceCodes.length; ++i) { |
| 764 var uiSourceCode = uiSourceCodes[i]; | 723 var uiSourceCode = uiSourceCodes[i]; |
| 765 if (url !== uiSourceCode.parentURL()) | 724 if (url !== uiSourceCode.parentURL()) |
| 766 continue; | 725 continue; |
| 767 if (fileNamePrefix(uiSourceCode.name()) === namePrefix) | 726 if (fileNamePrefix(uiSourceCode.name()) === namePrefix) |
| 768 candidates.push(uiSourceCode.name()); | 727 candidates.push(uiSourceCode.name()); |
| 769 } | 728 } |
| 770 candidates.sort(String.naturalOrderComparator); | 729 candidates.sort(String.naturalOrderComparator); |
| 771 var index = mod(candidates.indexOf(name) + 1, candidates.length); | 730 var index = mod(candidates.indexOf(name) + 1, candidates.length); |
| 772 var fullURL = (url ? url + "/" : "") + candidates[index]; | 731 var fullURL = (url ? url + '/' : '') + candidates[index]; |
| 773 var nextUISourceCode = currentUISourceCode.project().uiSourceCodeForURL(full
URL); | 732 var nextUISourceCode = currentUISourceCode.project().uiSourceCodeForURL(full
URL); |
| 774 return nextUISourceCode !== currentUISourceCode ? nextUISourceCode : null; | 733 return nextUISourceCode !== currentUISourceCode ? nextUISourceCode : null; |
| 734 } |
| 735 |
| 736 /** |
| 737 * @override |
| 738 * @param {!WebInspector.Context} context |
| 739 * @param {string} actionId |
| 740 * @return {boolean} |
| 741 */ |
| 742 handleAction(context, actionId) { |
| 743 var sourcesView = WebInspector.context.flavor(WebInspector.SourcesView); |
| 744 var currentUISourceCode = sourcesView.currentUISourceCode(); |
| 745 if (!currentUISourceCode) |
| 746 return false; |
| 747 var nextUISourceCode = WebInspector.SourcesView.SwitchFileActionDelegate._ne
xtFile(currentUISourceCode); |
| 748 if (!nextUISourceCode) |
| 749 return false; |
| 750 sourcesView.showSourceLocation(nextUISourceCode); |
| 751 return true; |
| 752 } |
| 775 }; | 753 }; |
| 776 | 754 |
| 777 | 755 |
| 778 WebInspector.SourcesView.SwitchFileActionDelegate.prototype = { | 756 /** |
| 779 /** | 757 * @implements {WebInspector.ActionDelegate} |
| 780 * @override | 758 * @unrestricted |
| 781 * @param {!WebInspector.Context} context | 759 */ |
| 782 * @param {string} actionId | 760 WebInspector.SourcesView.CloseAllActionDelegate = class { |
| 783 * @return {boolean} | 761 /** |
| 784 */ | 762 * @override |
| 785 handleAction: function(context, actionId) | 763 * @param {!WebInspector.Context} context |
| 786 { | 764 * @param {string} actionId |
| 787 var sourcesView = WebInspector.context.flavor(WebInspector.SourcesView); | 765 * @return {boolean} |
| 788 var currentUISourceCode = sourcesView.currentUISourceCode(); | 766 */ |
| 789 if (!currentUISourceCode) | 767 handleAction(context, actionId) { |
| 790 return false; | 768 var sourcesView = WebInspector.context.flavor(WebInspector.SourcesView); |
| 791 var nextUISourceCode = WebInspector.SourcesView.SwitchFileActionDelegate
._nextFile(currentUISourceCode); | 769 if (!sourcesView) |
| 792 if (!nextUISourceCode) | 770 return false; |
| 793 return false; | 771 sourcesView._editorContainer.closeAllFiles(); |
| 794 sourcesView.showSourceLocation(nextUISourceCode); | 772 return true; |
| 795 return true; | 773 } |
| 796 } | |
| 797 }; | 774 }; |
| 798 | |
| 799 /** | |
| 800 * @constructor | |
| 801 * @implements {WebInspector.ActionDelegate} | |
| 802 */ | |
| 803 WebInspector.SourcesView.CloseAllActionDelegate = function() | |
| 804 { | |
| 805 }; | |
| 806 | |
| 807 WebInspector.SourcesView.CloseAllActionDelegate.prototype = { | |
| 808 /** | |
| 809 * @override | |
| 810 * @param {!WebInspector.Context} context | |
| 811 * @param {string} actionId | |
| 812 * @return {boolean} | |
| 813 */ | |
| 814 handleAction: function(context, actionId) | |
| 815 { | |
| 816 var sourcesView = WebInspector.context.flavor(WebInspector.SourcesView); | |
| 817 if (!sourcesView) | |
| 818 return false; | |
| 819 sourcesView._editorContainer.closeAllFiles(); | |
| 820 return true; | |
| 821 } | |
| 822 }; | |
| OLD | NEW |