1/*
2 * Copyright (C) 2012 Google 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 are
6 * met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC.
20 * OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/**
30 * @constructor
31 * @extends {WebInspector.SourceFrame}
32 * @param {WebInspector.UISourceCode} uiSourceCode
33 */
34WebInspector.UISourceCodeFrame = function(uiSourceCode)
35{
36    this._uiSourceCode = uiSourceCode;
37    WebInspector.SourceFrame.call(this, this._uiSourceCode);
38    this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.FormattedChanged, this._onFormattedChanged, this);
39    this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyChanged, this._onWorkingCopyChanged, this);
40    this._uiSourceCode.addEventListener(WebInspector.UISourceCode.Events.WorkingCopyCommitted, this._onWorkingCopyCommitted, this);
41}
42
43WebInspector.UISourceCodeFrame.prototype = {
44    wasShown: function()
45    {
46        WebInspector.SourceFrame.prototype.wasShown.call(this);
47        this._boundWindowFocused = this._windowFocused.bind(this);
48        window.addEventListener("focus", this._boundWindowFocused, false);
49        this._checkContentUpdated();
50    },
51
52    willHide: function()
53    {
54        WebInspector.SourceFrame.prototype.willHide.call(this);
55        window.removeEventListener("focus", this._boundWindowFocused, false);
56        delete this._boundWindowFocused;
57    },
58
59    /**
60     * @return {boolean}
61     */
62    canEditSource: function()
63    {
64        return this._uiSourceCode.isEditable();
65    },
66
67    _windowFocused: function(event)
68    {
69        this._checkContentUpdated();
70    },
71
72    _checkContentUpdated: function()
73    {
74        if (!this.loaded || !this.isShowing())
75            return;
76        this._uiSourceCode.checkContentUpdated();
77    },
78
79    /**
80     * @param {string} text
81     */
82    commitEditing: function(text)
83    {
84        if (!this._uiSourceCode.isDirty())
85            return;
86
87        this._isCommittingEditing = true;
88        this._uiSourceCode.commitWorkingCopy(this._didEditContent.bind(this));
89        delete this._isCommittingEditing;
90    },
91
92    onTextChanged: function(oldRange, newRange)
93    {
94        WebInspector.SourceFrame.prototype.onTextChanged.call(this, oldRange, newRange);
95        this._isSettingWorkingCopy = true;
96        this._uiSourceCode.setWorkingCopy(this._textEditor.text());
97        delete this._isSettingWorkingCopy;
98    },
99
100    _didEditContent: function(error)
101    {
102        if (error) {
103            WebInspector.log(error, WebInspector.ConsoleMessage.MessageLevel.Error, true);
104            return;
105        }
106    },
107
108    /**
109     * @param {WebInspector.Event} event
110     */
111    _onFormattedChanged: function(event)
112    {
113        var content = /** @type {string} */ (event.data.content);
114        this._textEditor.setReadOnly(this._uiSourceCode.formatted());
115        this.setContent(content, false, this._uiSourceCode.mimeType());
116    },
117
118    /**
119     * @param {WebInspector.Event} event
120     */
121    _onWorkingCopyChanged: function(event)
122    {
123        this._innerSetContent(this._uiSourceCode.workingCopy());
124    },
125
126    /**
127     * @param {WebInspector.Event} event
128     */
129    _onWorkingCopyCommitted: function(event)
130    {
131        this._innerSetContent(this._uiSourceCode.workingCopy());
132    },
133
134    /**
135     * @param {string} content
136     */
137    onUISourceCodeContentChanged: function(content)
138    {
139        this.setContent(content, false, this._uiSourceCode.mimeType());
140    },
141
142    /**
143     * @param {string} content
144     */
145    _innerSetContent: function(content)
146    {
147        if (this._isSettingWorkingCopy || this._isCommittingEditing)
148            return;
149        this.onUISourceCodeContentChanged(content);
150    },
151
152    populateTextAreaContextMenu: function(contextMenu, lineNumber)
153    {
154        WebInspector.SourceFrame.prototype.populateTextAreaContextMenu.call(this, contextMenu, lineNumber);
155        contextMenu.appendApplicableItems(this._uiSourceCode);
156        contextMenu.appendSeparator();
157    },
158
159    dispose: function()
160    {
161        this.detach();
162    },
163
164    __proto__: WebInspector.SourceFrame.prototype
165}
166