Web Inspector: Line error widget showed in the wrong resource
[WebKit-https.git] / Source / WebInspectorUI / UserInterface / Views / ContentView.js
1 /*
2  * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 WebInspector.ContentView = class ContentView extends WebInspector.View
27 {
28     constructor(representedObject, extraArguments)
29     {
30         // Concrete object instantiation.
31         console.assert(!representedObject || WebInspector.ContentView.isViewable(representedObject), representedObject);
32
33         super();
34
35         this._representedObject = representedObject;
36
37         this.element.classList.add("content-view");
38
39         this._parentContainer = null;
40     }
41
42     // Static
43
44     static createFromRepresentedObject(representedObject, extraArguments)
45     {
46         console.assert(representedObject);
47
48         if (representedObject instanceof WebInspector.Frame)
49             return new WebInspector.ResourceClusterContentView(representedObject.mainResource, extraArguments);
50
51         if (representedObject instanceof WebInspector.Resource)
52             return new WebInspector.ResourceClusterContentView(representedObject, extraArguments);
53
54         if (representedObject instanceof WebInspector.Script)
55             return new WebInspector.ScriptContentView(representedObject, extraArguments);
56
57         if (representedObject instanceof WebInspector.TimelineRecording)
58             return new WebInspector.TimelineRecordingContentView(representedObject, extraArguments);
59
60         if (representedObject instanceof WebInspector.Timeline) {
61             var timelineType = representedObject.type;
62             if (timelineType === WebInspector.TimelineRecord.Type.Network)
63                 return new WebInspector.NetworkTimelineView(representedObject, extraArguments);
64
65             if (timelineType === WebInspector.TimelineRecord.Type.Layout)
66                 return new WebInspector.LayoutTimelineView(representedObject, extraArguments);
67
68             if (timelineType === WebInspector.TimelineRecord.Type.Script)
69                 return new WebInspector.ScriptClusterTimelineView(representedObject, extraArguments);
70
71             if (timelineType === WebInspector.TimelineRecord.Type.RenderingFrame)
72                 return new WebInspector.RenderingFrameTimelineView(representedObject, extraArguments);
73
74             if (timelineType === WebInspector.TimelineRecord.Type.Memory)
75                 return new WebInspector.MemoryTimelineView(representedObject, extraArguments);
76
77             if (timelineType === WebInspector.TimelineRecord.Type.HeapAllocations)
78                 return new WebInspector.HeapAllocationsTimelineView(representedObject, extraArguments);
79         }
80
81         if (representedObject instanceof WebInspector.Breakpoint || representedObject instanceof WebInspector.IssueMessage) {
82             if (representedObject.sourceCodeLocation)
83                 return WebInspector.ContentView.createFromRepresentedObject(representedObject.sourceCodeLocation.displaySourceCode, extraArguments);
84         }
85
86         if (representedObject instanceof WebInspector.DOMStorageObject)
87             return new WebInspector.DOMStorageContentView(representedObject, extraArguments);
88
89         if (representedObject instanceof WebInspector.CookieStorageObject)
90             return new WebInspector.CookieStorageContentView(representedObject, extraArguments);
91
92         if (representedObject instanceof WebInspector.DatabaseTableObject)
93             return new WebInspector.DatabaseTableContentView(representedObject, extraArguments);
94
95         if (representedObject instanceof WebInspector.DatabaseObject)
96             return new WebInspector.DatabaseContentView(representedObject, extraArguments);
97
98         if (representedObject instanceof WebInspector.IndexedDatabaseObjectStore)
99             return new WebInspector.IndexedDatabaseObjectStoreContentView(representedObject, extraArguments);
100
101         if (representedObject instanceof WebInspector.IndexedDatabaseObjectStoreIndex)
102             return new WebInspector.IndexedDatabaseObjectStoreContentView(representedObject, extraArguments);
103
104         if (representedObject instanceof WebInspector.ApplicationCacheFrame)
105             return new WebInspector.ApplicationCacheFrameContentView(representedObject, extraArguments);
106
107         if (representedObject instanceof WebInspector.DOMTree)
108             return new WebInspector.FrameDOMTreeContentView(representedObject, extraArguments);
109
110         if (representedObject instanceof WebInspector.DOMSearchMatchObject) {
111             var resultView = new WebInspector.FrameDOMTreeContentView(WebInspector.frameResourceManager.mainFrame.domTree, extraArguments);
112             resultView.restoreFromCookie({nodeToSelect: representedObject.domNode});
113             return resultView;
114         }
115
116         if (representedObject instanceof WebInspector.SourceCodeSearchMatchObject) {
117             var resultView;
118             if (representedObject.sourceCode instanceof WebInspector.Resource)
119                 resultView = new WebInspector.ResourceClusterContentView(representedObject.sourceCode, extraArguments);
120             else if (representedObject.sourceCode instanceof WebInspector.Script)
121                 resultView = new WebInspector.ScriptContentView(representedObject.sourceCode, extraArguments);
122             else
123                 console.error("Unknown SourceCode", representedObject.sourceCode);
124
125             var textRangeToSelect = representedObject.sourceCodeTextRange.formattedTextRange;
126             var startPosition = textRangeToSelect.startPosition();
127             resultView.restoreFromCookie({lineNumber: startPosition.lineNumber, columnNumber: startPosition.columnNumber});
128
129             return resultView;
130         }
131
132         if (representedObject instanceof WebInspector.LogObject)
133             return new WebInspector.LogContentView(representedObject, extraArguments);
134
135         if (representedObject instanceof WebInspector.ContentFlow)
136             return new WebInspector.ContentFlowDOMTreeContentView(representedObject, extraArguments);
137
138         if (representedObject instanceof WebInspector.CallingContextTree)
139             return new WebInspector.ProfileView(representedObject, extraArguments);
140
141         if (representedObject instanceof WebInspector.HeapSnapshotProxy || representedObject instanceof WebInspector.HeapSnapshotDiffProxy)
142             return new WebInspector.HeapSnapshotClusterContentView(representedObject, extraArguments);
143
144         if (typeof representedObject === "string" || representedObject instanceof String)
145             return new WebInspector.TextContentView(representedObject, extraArguments);
146
147         console.assert(!WebInspector.ContentView.isViewable(representedObject));
148
149         throw new Error("Can't make a ContentView for an unknown representedObject of type: " + representedObject.constructor.name);
150     }
151
152     static contentViewForRepresentedObject(representedObject, onlyExisting, extraArguments)
153     {
154         console.assert(representedObject);
155
156         // Some represented objects attempt to resolve a better represented object.
157         // This may result in null, for example a Breakpoint which doesn't have a SourceCode.
158         let resolvedRepresentedObject = WebInspector.ContentView.resolvedRepresentedObjectForRepresentedObject(representedObject);
159         if (!resolvedRepresentedObject)
160             return null;
161
162         let existingContentView = resolvedRepresentedObject[WebInspector.ContentView.ContentViewForRepresentedObjectSymbol];
163         console.assert(!existingContentView || existingContentView instanceof WebInspector.ContentView);
164         if (existingContentView)
165             return existingContentView;
166
167         if (onlyExisting)
168             return null;
169
170         let newContentView = WebInspector.ContentView.createFromRepresentedObject(representedObject, extraArguments);
171         console.assert(newContentView instanceof WebInspector.ContentView);
172         if (!newContentView)
173             return null;
174
175         console.assert(newContentView.representedObject === resolvedRepresentedObject, "createFromRepresentedObject and resolvedRepresentedObjectForRepresentedObject are out of sync for type", representedObject.constructor.name);
176         newContentView.representedObject[WebInspector.ContentView.ContentViewForRepresentedObjectSymbol] = newContentView;
177         return newContentView;
178     }
179
180     static closedContentViewForRepresentedObject(representedObject)
181     {
182         let resolvedRepresentedObject = WebInspector.ContentView.resolvedRepresentedObjectForRepresentedObject(representedObject);
183         resolvedRepresentedObject[WebInspector.ContentView.ContentViewForRepresentedObjectSymbol] = null;
184     }
185
186     static resolvedRepresentedObjectForRepresentedObject(representedObject)
187     {
188         if (representedObject instanceof WebInspector.Frame)
189             return representedObject.mainResource;
190
191         if (representedObject instanceof WebInspector.Breakpoint || representedObject instanceof WebInspector.IssueMessage) {
192             if (representedObject.sourceCodeLocation)
193                 return representedObject.sourceCodeLocation.displaySourceCode;
194         }
195
196         if (representedObject instanceof WebInspector.DOMSearchMatchObject)
197             return WebInspector.frameResourceManager.mainFrame.domTree;
198
199         if (representedObject instanceof WebInspector.SourceCodeSearchMatchObject)
200             return representedObject.sourceCode;
201
202         return representedObject;
203     }
204
205     static isViewable(representedObject)
206     {
207         if (representedObject instanceof WebInspector.Frame)
208             return true;
209         if (representedObject instanceof WebInspector.Resource)
210             return true;
211         if (representedObject instanceof WebInspector.Script)
212             return true;
213         if (representedObject instanceof WebInspector.TimelineRecording)
214             return true;
215         if (representedObject instanceof WebInspector.Timeline)
216             return true;
217         if (representedObject instanceof WebInspector.Breakpoint || representedObject instanceof WebInspector.IssueMessage)
218             return representedObject.sourceCodeLocation;
219         if (representedObject instanceof WebInspector.DOMStorageObject)
220             return true;
221         if (representedObject instanceof WebInspector.CookieStorageObject)
222             return true;
223         if (representedObject instanceof WebInspector.DatabaseTableObject)
224             return true;
225         if (representedObject instanceof WebInspector.DatabaseObject)
226             return true;
227         if (representedObject instanceof WebInspector.IndexedDatabaseObjectStore)
228             return true;
229         if (representedObject instanceof WebInspector.IndexedDatabaseObjectStoreIndex)
230             return true;
231         if (representedObject instanceof WebInspector.ApplicationCacheFrame)
232             return true;
233         if (representedObject instanceof WebInspector.DOMTree)
234             return true;
235         if (representedObject instanceof WebInspector.DOMSearchMatchObject)
236             return true;
237         if (representedObject instanceof WebInspector.SourceCodeSearchMatchObject)
238             return true;
239         if (representedObject instanceof WebInspector.LogObject)
240             return true;
241         if (representedObject instanceof WebInspector.ContentFlow)
242             return true;
243         if (representedObject instanceof WebInspector.CallingContextTree)
244             return true;
245         if (representedObject instanceof WebInspector.HeapSnapshotProxy || representedObject instanceof WebInspector.HeapSnapshotDiffProxy)
246             return true;
247         if (typeof representedObject === "string" || representedObject instanceof String)
248             return true;
249         return false;
250     }
251
252     // Public
253
254     get representedObject()
255     {
256         return this._representedObject;
257     }
258
259     get navigationItems()
260     {
261         // Navigation items that will be displayed by the ContentBrowser instance,
262         // meant to be subclassed. Implemented by subclasses.
263         return [];
264     }
265
266     get parentContainer()
267     {
268         return this._parentContainer;
269     }
270
271     get visible()
272     {
273         return this._visible;
274     }
275
276     set visible(flag)
277     {
278         this._visible = flag;
279     }
280
281     get scrollableElements()
282     {
283         // Implemented by subclasses.
284         return [];
285     }
286
287     get shouldKeepElementsScrolledToBottom()
288     {
289         // Implemented by subclasses.
290         return false;
291     }
292
293     get selectionPathComponents()
294     {
295         // Implemented by subclasses.
296         return [];
297     }
298
299     get supplementalRepresentedObjects()
300     {
301         // Implemented by subclasses.
302         return [];
303     }
304
305     get supportsSplitContentBrowser()
306     {
307         // Implemented by subclasses.
308         return true;
309     }
310
311     shown()
312     {
313         // Implemented by subclasses.
314     }
315
316     hidden()
317     {
318         // Implemented by subclasses.
319     }
320
321     closed()
322     {
323         // Implemented by subclasses.
324     }
325
326     saveToCookie(cookie)
327     {
328         // Implemented by subclasses.
329     }
330
331     restoreFromCookie(cookie)
332     {
333         // Implemented by subclasses.
334     }
335
336     canGoBack()
337     {
338         // Implemented by subclasses.
339         return false;
340     }
341
342     canGoForward()
343     {
344         // Implemented by subclasses.
345         return false;
346     }
347
348     goBack()
349     {
350         // Implemented by subclasses.
351     }
352
353     goForward()
354     {
355         // Implemented by subclasses.
356     }
357
358     get supportsSearch()
359     {
360         // Implemented by subclasses.
361         return false;
362     }
363
364     get numberOfSearchResults()
365     {
366         // Implemented by subclasses.
367         return null;
368     }
369
370     get hasPerformedSearch()
371     {
372         // Implemented by subclasses.
373         return false;
374     }
375
376     set automaticallyRevealFirstSearchResult(reveal)
377     {
378         // Implemented by subclasses.
379     }
380
381     performSearch(query)
382     {
383         // Implemented by subclasses.
384     }
385
386     searchCleared()
387     {
388         // Implemented by subclasses.
389     }
390
391     searchQueryWithSelection()
392     {
393         // Implemented by subclasses.
394         return null;
395     }
396
397     revealPreviousSearchResult(changeFocus)
398     {
399         // Implemented by subclasses.
400     }
401
402     revealNextSearchResult(changeFocus)
403     {
404         // Implemented by subclasses.
405     }
406 };
407
408 WebInspector.ContentView.Event = {
409     SelectionPathComponentsDidChange: "content-view-selection-path-components-did-change",
410     SupplementalRepresentedObjectsDidChange: "content-view-supplemental-represented-objects-did-change",
411     NumberOfSearchResultsDidChange: "content-view-number-of-search-results-did-change",
412     NavigationItemsDidChange: "content-view-navigation-items-did-change"
413 };
414
415 WebInspector.ContentView.ContentViewForRepresentedObjectSymbol = Symbol("content-view-for-represented-object");