1/*
2 * Copyright (C) 2013 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
26WebInspector.FrameContentView = function(frame)
27{
28    WebInspector.ClusterContentView.call(this, frame);
29
30    this._frame = frame;
31
32    function createPathComponent(displayName, className, identifier)
33    {
34        var pathComponent = new WebInspector.HierarchicalPathComponent(displayName, className, identifier, false, true);
35        pathComponent.addEventListener(WebInspector.HierarchicalPathComponent.Event.SiblingWasSelected, this._pathComponentSelected, this);
36        return pathComponent;
37    }
38
39    this._sourceCodePathComponent = createPathComponent.call(this, WebInspector.UIString("Source Code"), WebInspector.FrameContentView.SourceCodeIconStyleClassName, WebInspector.FrameContentView.SourceCodeIdentifier);
40    this._domTreePathComponent = createPathComponent.call(this, WebInspector.UIString("DOM Tree"), WebInspector.FrameContentView.DOMTreeIconStyleClassName, WebInspector.FrameContentView.DOMTreeIdentifier);
41
42    this._sourceCodePathComponent.nextSibling = this._domTreePathComponent;
43    this._domTreePathComponent.previousSibling = this._sourceCodePathComponent;
44
45    this.element.classList.add(WebInspector.FrameContentView.StyleClassName);
46
47    this._currentContentViewSetting = new WebInspector.Setting("frame-current-view-" + this._frame.url.hash, WebInspector.FrameContentView.DOMTreeIdentifier);
48};
49
50WebInspector.FrameContentView.StyleClassName = "frame";
51WebInspector.FrameContentView.SourceCodeIconStyleClassName = "source-code-icon";
52WebInspector.FrameContentView.SourceCodeIdentifier = "source-code";
53WebInspector.FrameContentView.DOMTreeIconStyleClassName = "dom-tree-icon";
54WebInspector.FrameContentView.DOMTreeIdentifier = "dom-tree";
55
56WebInspector.FrameContentView.prototype = {
57    constructor: WebInspector.FrameContentView,
58
59    // Public
60
61    get frame()
62    {
63        return this._frame;
64    },
65
66    get selectionPathComponents()
67    {
68        if (!this._contentViewContainer.currentContentView)
69            return [];
70
71        // Append the current view's path components to the path component representing the current view.
72        var components = [this._pathComponentForContentView(this._contentViewContainer.currentContentView)];
73        return components.concat(this._contentViewContainer.currentContentView.selectionPathComponents);
74    },
75
76    shown: function()
77    {
78        WebInspector.ClusterContentView.prototype.shown.call(this);
79
80        if (this._shownInitialContent)
81            return;
82
83        this._showContentViewForIdentifier(this._currentContentViewSetting.value);
84    },
85
86    closed: function()
87    {
88        WebInspector.ClusterContentView.prototype.closed.call(this);
89
90        this._shownInitialContent = false;
91    },
92
93    saveToCookie: function(cookie)
94    {
95        cookie.type = WebInspector.ContentViewCookieType.Resource;
96        cookie.subview = this._currentContentViewSetting.value;
97        if (!this.representedObject.isMainFrame())
98            cookie.url = this.representedObject.url;
99    },
100
101    restoreFromCookie: function(cookie)
102    {
103        var shownView = this._showContentViewForIdentifier(cookie.subview);
104        if ("lineNumber" in cookie && "columnNumber" in cookie)
105            this.showSourceCode(new WebInspector.SourceCodePosition(cookie.lineNumber, cookie.columnNumber));
106    },
107
108    showResource: function()
109    {
110        this._shownInitialContent = true;
111
112        return this._showContentViewForIdentifier(WebInspector.FrameContentView.SourceCodeIdentifier);
113    },
114
115    showSourceCode: function(positionToReveal, textRangeToSelect, forceUnformatted)
116    {
117        var resourceContentView = this.showResource();
118        console.assert(resourceContentView instanceof WebInspector.ResourceClusterContentView);
119        if (!resourceContentView)
120            return null;
121
122        return resourceContentView.showResponse(positionToReveal, textRangeToSelect, forceUnformatted);
123    },
124
125    showDOMTree: function(domNodeToSelect, preventFocusChange)
126    {
127        this._shownInitialContent = true;
128
129        var domTreeContentView = this._showContentViewForIdentifier(WebInspector.FrameContentView.DOMTreeIdentifier);
130        console.assert(domTreeContentView);
131        if (!domTreeContentView || !domNodeToSelect)
132            return null;
133
134        domTreeContentView.selectAndRevealDOMNode(domNodeToSelect, preventFocusChange);
135
136        return domTreeContentView;
137    },
138
139    // Private
140
141    _pathComponentForContentView: function(contentView)
142    {
143        console.assert(contentView);
144        if (!contentView)
145            return null;
146        if (contentView.representedObject instanceof WebInspector.Resource)
147            return this._sourceCodePathComponent;
148        if (contentView.representedObject instanceof WebInspector.DOMTree)
149            return this._domTreePathComponent;
150        console.error("Unknown contentView.");
151        return null;
152    },
153
154    _identifierForContentView: function(contentView)
155    {
156        console.assert(contentView);
157        if (!contentView)
158            return null;
159        if (contentView.representedObject instanceof WebInspector.Resource)
160            return WebInspector.FrameContentView.SourceCodeIdentifier;
161        if (contentView.representedObject instanceof WebInspector.DOMTree)
162            return WebInspector.FrameContentView.DOMTreeIdentifier;
163        console.error("Unknown contentView.");
164        return null;
165    },
166
167    _showContentViewForIdentifier: function(identifier)
168    {
169        var representedObjectToShow = null;
170
171        switch (identifier) {
172        case WebInspector.FrameContentView.SourceCodeIdentifier:
173            representedObjectToShow = this._frame.mainResource;
174            break;
175        case WebInspector.FrameContentView.DOMTreeIdentifier:
176            representedObjectToShow = this._frame.domTree;
177            break;
178        }
179
180        console.assert(representedObjectToShow);
181        if (!representedObjectToShow)
182            return;
183
184        this._currentContentViewSetting.value = identifier;
185
186        return this.contentViewContainer.showContentViewForRepresentedObject(representedObjectToShow);
187    },
188
189    _pathComponentSelected: function(event)
190    {
191        this._showContentViewForIdentifier(event.data.pathComponent.representedObject);
192    }
193};
194
195WebInspector.FrameContentView.prototype.__proto__ = WebInspector.ClusterContentView.prototype;
196